pyenvからの卒業

Linuxを入れ直したので、Pythonの環境構築を一からやり直すことになりました。
著名なpythonistaの人たちが、pyenvとかを使うんじゃなくてPythonを直接インストールしたほうが良いよ、とおっしゃっているのでその道を進むことにしました。
なお、Linux Mint 19環境です。

ビルド

さて、自分でPythonをビルドする、という事はインストール先を自分で決める必要が有ります。
バックアップとかも楽ちんになるので、私は基本的にホームディレクトリ配下にインストールする派です。

ということで、Pythonのインストール先は$HOME/opt/pythonとしました。
早速ディレクトリを作っておきます。

[koji:~]$ mkdir -p $HOME/opt/python

ダウンロードとビルド

Python公式からソースをダウンロードして、解凍後にビルドします。
なお、configureのオプションは最低限必要なものです。必要に応じでconfigureを指定する必要が有ります。

[koji:src]$ pwd
/home/koji/src
[koji:src]$ wget https://www.python.org/ftp/python/3.7.2/Python-3.7.2.tar.xz
[koji:src]$ xz -dc Python-3.7.2.tar.xz| tar xfv -
[koji:src]$ cd Python-3.7.2
[koji:Python-3.7.2]$ ./configure --prefix=/home/koji/opt/python --with-ensurepip=install
[koji:Python-3.7.2]$ make 2>&1 | tee make.log
[koji:Python-3.7.2]$ make altinstall

コレで完了です!
結果は以下に示しますが、make installじゃなくて、make altinstallを利用した、という点が非常に重要です。

ビルド結果の確認

ではビルド結果を見てみます。ビルド

[koji:~]$ cd $HOME/opt/python 
[koji:python]$ ls
bin  include  lib  share
[koji:python]$

Python用のディレクトリができています。

そしてbinの中身を見てみると。。。

[koji:python]$ cd bin
[koji:bin]$ ls -alh
合計 29M
drwxr-xr-x 2 koji koji 4,0K  1月 21 16:22 .
drwxr-xr-x 6 koji koji 4,0K  1月 21 16:22 ..
-rwxr-xr-x 1 koji koji  112  1月 21 16:22 2to3-3.7
-rwxr-xr-x 1 koji koji  253  1月 21 16:22 easy_install-3.7
-rwxr-xr-x 1 koji koji  110  1月 21 16:22 idle3.7
-rwxr-xr-x 1 koji koji  235  1月 21 16:22 pip3.7
-rwxr-xr-x 1 koji koji   95  1月 21 16:22 pydoc3.7
-rwxr-xr-x 2 koji koji  15M  1月 21 16:21 python3.7
-rwxr-xr-x 2 koji koji  15M  1月 21 16:21 python3.7m
-rwxr-xr-x 1 koji koji 3,1K  1月 21 16:22 python3.7m-config
-rwxr-xr-x 1 koji koji  452  1月 21 16:22 pyvenv-3.7
[koji:bin]$

普通にバイナリが生成されています。良い感じです。
が、良くよく見てみると、pythonpython3といった重要なコマンドが生成されていません。
実は、prefixを指定せずにmake installを実行すると、Linuxが標準で持っているpython, python3コマンドが上書きされてしまいます。
コレが原因で、別のツールが使っているpythonのバージョンと異なるものになってしまって動かなくなってしまった、という話をよく見かけます。

今回、make installの代わりに、make altinstallを利用しました。
コレは、単純に 既存のpythonpython3を置き換えるシンボリックリンクを作成しない、と言うものになります。
そのため、既存の環境を壊すことなく安心してメジャーバージョンの異なる複数のPythonをインストールすることができます。

今回はOS標準のインストール先を利用しないようにprefixを指定した上で、さらにmake altinstallを実行することでバージョン名が付いたpythonバイナリ群のみを生成しました。
安全の上に安心を築き上げる慎重さ!

なお、当然こんな場所にパスは通っていないのでパスを通してあげる必要が有ります。
私はzshを利用しているので、以下のような内容を .zshenvに追記しました。

export ALT_PYTHON=$HOME/opt/python
path=(
    $ALT_PYTHON/bin
)

バージョンの確認

LinuxMint19には標準でpython2.7python3.6、そしてそれらのリンクであるpython, python2, python2.7, python3, python3.6が存在しています。
そして今回インストールしたのがPython3.7です。
実際に確認してみます。

### まずは2系(標準)
[koji:Python-3.7.2]$ python --version
Python 2.7.15rc1
[koji:Python-3.7.2]$ python2 --version
Python 2.7.15rc1
[koji:Python-3.7.2]$ python2.7 --version
Python 2.7.15rc1

### 次に3.6(標準)
koji:Python-3.7.2]$ python3 --version
Python 3.6.7
[koji:Python-3.7.2]$ python3.6 --version
Python 3.6.7
[koji:Python-3.7.2]$ 

### そして今回インストールした3.7
[koji:Python-3.7.2]$ python3.7 --version
Python 3.7.2

ちゃんと標準のPythonを壊すことなく、新たにPython3.7をインストールできていることが確認できました!

configureを指定し直して再度ビルドする場合

自分でビルドすると、間違いなく後々configureを指定しなおして再度ビルドする機会が出てきます。
その際には当然すでに指定したconfigureのオプションも指定しないといけませんが、そんなの覚えていない。。。
ということで、実は直前のconfigureオプションは、ソースディレクトリにconfig.logという名前で出力されています。

config.logを開くと、先頭に実行したconfigureオプションが出力されていますので、その内容に新しく追加したいcofnigureオプションをを追記して再度configureを実行すればOKです。
※当然configureを実行するとその値で上書きされるので、事前にどこかにコピペしておいたほうが良いです

This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.

It was created by python configure 3.7, which was
generated by GNU Autoconf 2.69.  Invocation command line was

  $ ./configure --prefix=/home/koji/opt/python --with-ensurepip=install

venvを使って仮想環境を構築

さて、pythonでちょっとしたスクリプトを書く以上の規模になってくると、仮想環境を作ることになります。
仮想環境の作成も色々ツールが存在していますが、Python3.3からvenvという仮想環境用のモジュールが標準で入るようになりました。
ということで今後はこのvenvを利用することになると思われます。

能書きはココまでにして実際venvを使ってみます。

# 仮想環境を作成してactivate
[koji:python]$ cd
[koji:~]$ python3.7 -m venv 37sample
[koji:~]$ source 37sample/bin/activate

# pythonのバージョンを確認してみる
(37sample) [koji:~]$ python --version
Python 3.7.2
(37sample) [koji:~]$ python3 --version
Python 3.7.2
(37sample) [koji:~]$ python2 --version
Python 2.7.15rc1
(37sample) [koji:~]$

今回インストールしたPython3.7でvenvを使って仮想環境を作成しています。
そしてその仮想環境をactivateすると、pythonコマンド自体が環境を作成したPython3.7.2になってくれています。
コレは非常に便利ですね。
毎回開発する際にpython3.7、という感じでバージョンを指定する必要がなくなります。

なお、当然deactivateすればもとに戻ります。

(37sample) [koji:~]$ deactivate 
[koji:~]$ python --version 
Python 2.7.15rc1
[koji:~]$ python2 --version
Python 2.7.15rc1
[koji:~]$ python3 --version
Python 3.6.7
[koji:~]$

おまけ

vim-quickrunを利用している場合、.vimrcに以下の設定を追加することでPythonのバージョンを切り替えることができます。

let g:quickrun_config={
    \'python': {
    \   'command': 'python3.7'
    \}
\}