venvを使ったmacOSのPython開発環境2016

また開発でPythonをゴリゴリ書く環境になったので、折角なのでPython環境を整備した。
自分はWeb開発 + ちょっとしたスクリプトでの利用が中心で、今では2系のコードを扱うことが無くなった為、pyenv, pyenv-virtualenvの利用を辞め、venvを使う方法に変えた。
(追記: 2017/12/29 2017年現在もこの環境で開発中です。)

環境: OS X EL Capitan, High Sierra

# pyenv, pyenv-virtualenvをアンインストールする

[pyenvが必要かどうかフローチャート - Qiita](http://qiita.com/shibukawa/items/0daab479a2fd2cb8a0e7) に従い、pyenv, pyenv-virtualenvをアンインストールする。
詳しくはリンク先参照だが、開発環境の構築方法を探してこの記事に辿りついた人にpyenvは不要だと思われる。 

私も過去にはpyenvを使って.python-versionファイルを設置していたのだが、3.5.*のような指定はできないので、3.5.1から3.5.2へのマイナーバージョンのアップデートの度に.python-versionを書き換えていた。  
で、.python-versionは実行可能なバージョンを示すファイルなので当然git管理していたが、バージョンアップの度に余計なgitの歴史が追加されてしまうし、久し振りに実行しようとしたら、古いバージョンのPythonをインストールするか.python-versionを書き換えないとバージョンエラーで実行できないという面倒な自体に陥ってしまっていた。
  
しかし、そもそも現在個人で扱うのは3系のみでPythonのバージョン管理の必要が無い。
また、チームプロダクトで扱うものはDockerfileやその他でバージョンやパッケージ管理すればよいのでpyenvを使う必要は無いと判断した。  
過渡期にはお世話になりました。ありがとうpyenv。


```zsh
$ brew uninstall --force pyenv
$ brew uninstall --force pyenv-virtualenv
$ rm -rf .pyenv/
```


# イマドキのPython3系インストール & アップグレード

homebrewでインストールする

```zsh
$ brew install python3
```

Python3を呼び出すには `python3`, pipは `pip3` となる。  
pip3のupgradeを促されたら、

```zsh
$ pip3 install --upgrade pip
```

後は気の向いた時にでも brew upgrade してればOK.

```zsh
$ brew upgrade
```


# Vim

Python開発に関連したプラグインはこの3つ位。細かい使い方は公式ドキュメントに譲って割愛。

* Pythonの自動補完ライブラリ
  * [davidhalter/jedi-vim: Using the jedi autocompletion library for VIM.](https://github.com/davidhalter/jedi-vim)
* Vimでの非同期シンタックスチェックプラグイン
  * [osyo-manga/vim-watchdogs: Async syntax checking.](https://github.com/osyo-manga/vim-watchdogs)
* Vimでの実行結果出力プラグイン
  * [thinca/vim-quickrun: Run commands quickly.](https://github.com/thinca/vim-quickrun)

## quickrun.vimでの実行コマンドの指定

開発ではPython3系しか使わないが、 `python` コマンドではsystemのpython(osxでは2.7系)が実行されてしまうので、quickrun.vimでの実行コマンドは3系を実行するように指定する。

```vim
let g:quickrun_config = {
  \ 'python': {
  \   'command': 'python3'
  \ },
```

# グローバルに必要なパッケージのみ、グローバル環境にインストールする

グローバルな環境では、最低限のパッケージのみインストールする。
ここでは、エディタで利用するのに必要なflake8を例にインストールする。
他に必要なパッケージはDockerやvenv側でインストールするのでグローバルにはインストールしない。

```zsh
$ pip3 install flake8
Collecting flake8
  Downloading flake8-3.0.4-py2.py3-none-any.whl (64kB)
    100% |████████████████████████████████| 71kB 320kB/s
Collecting pycodestyle<2.1.0,>=2.0.0 (from flake8)
  Using cached pycodestyle-2.0.0-py2.py3-none-any.whl
Collecting mccabe<0.6.0,>=0.5.0 (from flake8)
  Downloading mccabe-0.5.2-py2.py3-none-any.whl
Collecting pyflakes!=1.2.0,!=1.2.1,!=1.2.2,<1.3.0,>=0.8.1 (from flake8)
  Using cached pyflakes-1.2.3-py2.py3-none-any.whl
Installing collected packages: pycodestyle, mccabe, pyflakes, flake8
Successfully installed flake8-3.0.4 mccabe-0.5.2 pycodestyle-2.0.0 pyflakes-1.2.3
```

# グローバルにインストールしたパッケージ管理ファイルをdotfilesに保持する

## パッケージ管理ファイル出力

`pip3 freeze` コマンドで、インストール済みパッケージリストを出力できるのでそれを利用する。

```zsh
$ pip3 freeze
flake8==3.0.4
mccabe==0.5.2
pycodestyle==2.0.0
pyflakes==1.2.3
```

Pythonでは通例的に requirements.txt として出力するので、慣例に倣う。

```zsh
# パッケージリストをrequirements.txtに出力
$ pip3 freeze > ~/dotfiles/requirements.txt
```

## パッケージ管理ファイルからインストール

新しい環境などでrequirements.txtを参照してインストールする場合には以下のコマンドを叩く。

```zsh
$ pip3 install -r ~/dotfiles/requirements.txt
```

## 補足: パッケージ一括アップデート

纏めて一括アップデートしたい場合には、以下のようなコマンドがあるので自分はエイリアスとして登録している。

```zsh
alias pip3_update_all='pip3 freeze --local | grep -v "^\-e" | cut -d = -f 1 | xargs pip3 install -U'
```

参考: [pipで一括アップデート - Qiita](http://qiita.com/manji-0/items/d3d824d77c18c2f28569)

## 補足: python / python3, pip / pip3コマンドについて

`$ python` はシステム依存の Python 2.7.10 で、 `$ python3` はHomebrewでインストールした Python 3。  
`$ pip` と `$ pip3` は共にHomebrewでインストールした Python 3 に紐づく。



```zsh
# python, python3パス,バージョンのチェック
$ where python
/usr/bin/python

$ where python3
/usr/local/bin/python3

$ python -V
Python 2.7.10

$ python3 -V
Python 3.5.2

# pip, pip3パス,バージョンのチェック
$ where pip
/usr/local/bin/pip

$ where pip3
/usr/local/bin/pip3

$ pip -V
pip 9.0.0 from /usr/local/lib/python3.5/site-packages (python 3.5)

$ pip3 -V
pip 9.0.0 from /usr/local/lib/python3.5/site-packages (python 3.5)
```

# venv を使う

Web開発に於いては基本的にDockerを利用するが、スクリプト実行などでローカル環境を使う場合には、必要に応じてPython3.3で追加されたvenv(virtualenvがPythonに取り込まれた。)を使って仮想環境を構築する。  
コマンドは `pyvenv` 。

#### 追記: 2017-05-31
Python 3.6からは `python3 -m venv` になり、 `pyvenv` は非推奨。

## 仮想環境を作る

```zsh
# myenvという名前で仮想環境を構築する
# Python 3.5以前
$ pyvenv myenv
# Python 3.6以降
$ python3 -m venv myenv



# activate
$ source myenv/bin/activate

# deactivate
$ deactivate
```

## 試しに仮想環境を有効化して仮想環境にパッケージをインストールしてみる。

仮想環境では、各環境用に必要なパッケージのみインストールする。

```zsh
# 仮想環境の有効化
$ source myenv/bin/activate 

# 試しにflaskをインストールしてみる
(myenv) $ pip install flask
Collecting flask
  Downloading Flask-0.11.1-py2.py3-none-any.whl (80kB)
    100% |████████████████████████████████| 81kB 2.3MB/s
Collecting Werkzeug>=0.7 (from flask)
  Downloading Werkzeug-0.11.11-py2.py3-none-any.whl (306kB)
    100% |████████████████████████████████| 307kB 2.5MB/s
Collecting click>=2.0 (from flask)
  Using cached click-6.6.tar.gz
Collecting itsdangerous>=0.21 (from flask)
  Downloading itsdangerous-0.24.tar.gz (46kB)
    100% |████████████████████████████████| 51kB 3.8MB/s
Collecting Jinja2>=2.4 (from flask)
  Downloading Jinja2-2.8-py2.py3-none-any.whl (263kB)
    100% |████████████████████████████████| 266kB 2.4MB/s
Collecting MarkupSafe (from Jinja2>=2.4->flask)
  Downloading MarkupSafe-0.23.tar.gz
Installing collected packages: Werkzeug, click, itsdangerous, MarkupSafe, Jinja2, flask
  Running setup.py install for click ... done
  Running setup.py install for itsdangerous ... done
  Running setup.py install for MarkupSafe ... done
Successfully installed Jinja2-2.8 MarkupSafe-0.23 Werkzeug-0.11.11 click-6.6 flask-0.11.1 itsdangerous-0.24

# パッケージリストを確認してみる(myenv仮想環境のパッケージリストが出力される)
(myenv) $ pip freeze
click==6.6
Flask==0.11.1
itsdangerous==0.24
Jinja2==2.8
MarkupSafe==0.23
Werkzeug==0.11.11

# 仮想環境の無効化
$ deactivate

# パッケージリストを確認してみる(グローバル環境のパッケージリストが出力される)
$ pip3 freeze
flake8==3.0.4
mccabe==0.5.2
pycodestyle==2.0.0
pyflakes==1.2.3
```

参考: [28.3. venv — 仮想環境の作成 — Python 3.5.2 ドキュメント](http://docs.python.jp/3/library/venv.html)

仮想環境の切り替えが問題なくできることを確認できた。



## 補足: venv上のpython / python3, pip / pip3コマンドについて

仮想環境上では3無しのコマンドも同一のバージョンを指すため、3無しのコマンドを叩いても支障がない。

```zsh
# python, python3パス,バージョンのチェック
(myenv) $ where python
/Users/user_name/myenv/bin/python
/usr/bin/python

(myenv) $ where python3
/Users/user_name/myenv/bin/python3
/usr/local/bin/python3

(myenv) $ python -V
Python 3.5.2

(myenv) $ python3 -V
Python 3.5.2


# pip, pip3パス,バージョンのチェック
(myenv) $ where pip
/Users/user_name/myenv/bin/pip

(myenv) $ where pip3
/Users/user_name/myenv/bin/pip3

(myenv) $ pip -V
pip 9.0.0 from /Users/user_name/pyvenv/lib/python3.5/site-packages (python 3.5)

(myenv) $ pip3 -V
pip 9.0.0 from /Users/user_name/pyvenv/lib/python3.5/site-packages (python 3.5)
```

# 纏め

pyenv, pyenv-virtualenv無しのクリーンなPython環境を整えた。
今後は `brew upgrade` でPythonがアップデートされるし、新しい環境に引っ越した場合でも、 `pip3 install -r ~/dotfiles/requirements.txt` をするだけで良い。