Python3.7 + Pipenv環境をUbuntu18.04 LTSに構築

Ubuntu18.04 LTS上にPython3.7 + Pipenvの環境を構築していった記録です。
必要なのでpipもインストールしています。

# 環境

* OS: Ubuntu 18.04 LTS
* CPU: x86_64

# 手順

## `apt update` & `apt upgrade`

下準備として、updateとupgradeを行っておきます。

```bash
$ sudo apt update
$ sudo apt upgrade
```

## インストール可能なパッケージの確認

インストール可能なパッケージを確認しましょう。

```bash
$ sudo apt search python3.7-*
```

今回の環境では以下のようになりました。

```bash
Sorting... Done
Full Text Search... Done
idle-python3.7/bionic-updates,bionic-updates 3.7.1-1~18.04 all
  IDE for Python (v3.7) using Tkinter

libpython3.7/bionic-updates 3.7.1-1~18.04 amd64
  Shared Python runtime library (version 3.7)

libpython3.7-dbg/bionic-updates 3.7.1-1~18.04 amd64
  Debug Build of the Python Interpreter (version 3.7)

libpython3.7-dev/bionic-updates 3.7.1-1~18.04 amd64
  Header files and a static library for Python (v3.7)

libpython3.7-minimal/bionic-updates 3.7.1-1~18.04 amd64
  Minimal subset of the Python language (version 3.7)

libpython3.7-stdlib/bionic-updates 3.7.1-1~18.04 amd64
  Interactive high-level object-oriented language (standard library, version 3.7)

libpython3.7-testsuite/bionic-updates,bionic-updates 3.7.1-1~18.04 all
  Testsuite for the Python standard library (v3.7)

python3.7/bionic-updates 3.7.1-1~18.04 amd64
  Interactive high-level object-oriented language (version 3.7)

python3.7-dbg/bionic-updates 3.7.1-1~18.04 amd64
  Debug Build of the Python Interpreter (version 3.7)

python3.7-dev/bionic-updates 3.7.1-1~18.04 amd64
  Header files and a static library for Python (v3.7)

python3.7-doc/bionic-updates,bionic-updates 3.7.1-1~18.04 all
  Documentation for the high-level object-oriented language Python (v3.7)

python3.7-examples/bionic-updates,bionic-updates 3.7.1-1~18.04 all
  Examples for the Python language (v3.7)

python3.7-minimal/bionic-updates 3.7.1-1~18.04 amd64
  Minimal subset of the Python language (version 3.7)

python3.7-venv/bionic-updates 3.7.1-1~18.04 amd64
  Interactive high-level object-oriented language (pyvenv binary, version 3.7)
```


`python3.7`, `python3.7-dev`等色々あります。

これらのパッケージの役割の違いについては、packageの説明などを参照すると良いと思います。
https://packages.ubuntu.com/ja/bionic/python3-dev

## pythonインストール

それではpythonをインストールします。

```bash
$ sudo apt install python3.7 python3.7-dev
```

入りました。

```bash
$ python3.7 -V
Python 3.7.1
```

## pipのインストール

get-pipを使ってpipをインストールします。

参考: https://pip.pypa.io/en/stable/installing/

```bash
$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
$ python3.7 get-pip.py
```

エラーがおきました。

```bash
Traceback (most recent call last):
  File "get-pip.py", line 20890, in <module>
    main()
  File "get-pip.py", line 197, in main
    bootstrap(tmpdir=tmpdir)
  File "get-pip.py", line 82, in bootstrap
    import pip._internal
  File "/tmp/tmppxy0_niv/pip.zip/pip/_internal/__init__.py", line 40, in <module>
  File "/tmp/tmppxy0_niv/pip.zip/pip/_internal/cli/autocompletion.py", line 8, in <module>
  File "/tmp/tmppxy0_niv/pip.zip/pip/_internal/cli/main_parser.py", line 8, in <module>
  File "/tmp/tmppxy0_niv/pip.zip/pip/_internal/cli/cmdoptions.py", line 17, in <module>
  File "/tmp/tmppxy0_niv/pip.zip/pip/_internal/locations.py", line 10, in <module>
ImportError: cannot import name 'sysconfig' from 'distutils' (/usr/lib/python3.7/distutils/__init__.py)
Error in sys.excepthook:
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/apport_python_hook.py", line 63, in apport_excepthook
    from apport.fileutils import likely_packaged, get_recent_crashes
  File "/usr/lib/python3/dist-packages/apport/__init__.py", line 5, in <module>
    from apport.report import Report
  File "/usr/lib/python3/dist-packages/apport/report.py", line 30, in <module>
    import apport.fileutils
  File "/usr/lib/python3/dist-packages/apport/fileutils.py", line 23, in <module>
    from apport.packaging_impl import impl as packaging
  File "/usr/lib/python3/dist-packages/apport/packaging_impl.py", line 24, in <module>
    import apt
  File "/usr/lib/python3/dist-packages/apt/__init__.py", line 23, in <module>
    import apt_pkg
ModuleNotFoundError: No module named 'apt_pkg'

Original exception was:
Traceback (most recent call last):
  File "get-pip.py", line 20890, in <module>
    main()
  File "get-pip.py", line 197, in main
    bootstrap(tmpdir=tmpdir)
  File "get-pip.py", line 82, in bootstrap
    import pip._internal
  File "/tmp/tmppxy0_niv/pip.zip/pip/_internal/__init__.py", line 40, in <module>
  File "/tmp/tmppxy0_niv/pip.zip/pip/_internal/cli/autocompletion.py", line 8, in <module>
  File "/tmp/tmppxy0_niv/pip.zip/pip/_internal/cli/main_parser.py", line 8, in <module>
  File "/tmp/tmppxy0_niv/pip.zip/pip/_internal/cli/cmdoptions.py", line 17, in <module>
  File "/tmp/tmppxy0_niv/pip.zip/pip/_internal/locations.py", line 10, in <module>
ImportError: cannot import name 'sysconfig' from 'distutils' (/usr/lib/python3.7/distutils/__init__.py)
```

良くわかりませんが、get-pipが期待している一部のパッケージが見つからないようです。

詳しく理解していませんが、`sudo apt-get install python3-distutils`でこの問題を解消できたという情報があります。

https://github.com/pypa/pip/issues/5367#issuecomment-386864941

```bash
$ sudo apt install python3.7-distutils
$ python3.7 get-pip.py
```

結果: 先程のエラーは解消しましたが、今度はpermissionが無いと怒られます。

```bash
Collecting pip
  Downloading https://files.pythonhosted.org/packages/c2/d7/90f34cb0d83a6c5631cf71dfe64cc1054598c843a92b400e55675cc2ac37/pip-18.1-py2.py3-none-any.whl (1.3MB)
    100% |████████████████████████████████| 1.3MB 21.9MB/s 
Collecting setuptools
  Downloading https://files.pythonhosted.org/packages/37/06/754589caf971b0d2d48f151c2586f62902d93dc908e2fd9b9b9f6aa3c9dd/setuptools-40.6.3-py2.py3-none-any.whl (573kB)
    100% |████████████████████████████████| 573kB 46.0MB/s 
Collecting wheel
  Downloading https://files.pythonhosted.org/packages/ff/47/1dfa4795e24fd6f93d5d58602dd716c3f101cfd5a77cd9acbe519b44a0a9/wheel-0.32.3-py2.py3-none-any.whl
launchpadlib 1.10.6 requires testresources, which is not installed.
Installing collected packages: pip, setuptools, wheel
Could not install packages due to an EnvironmentError: [Errno 13] Permission denied: '/usr/local/lib/python3.7/dist-packages/pip-18.1.dist-info'
Consider using the `--user` option or check the permissions.
```

今回は`--user`オプションをつけて`/home`以下にインストールします。

```bash
$ python3.7 get-pip.py --user
```

「インストールしたディレクトリにPATHが通ってないよ」的なメッセージを出してくれました。親切ですね。

```
Collecting pip
  Using cached https://files.pythonhosted.org/packages/c2/d7/90f34cb0d83a6c5631cf71dfe64cc1054598c843a92b400e55675cc2ac37/pip-18.1-py2.py3-none-any.whl
Collecting setuptools
  Using cached https://files.pythonhosted.org/packages/37/06/754589caf971b0d2d48f151c2586f62902d93dc908e2fd9b9b9f6aa3c9dd/setuptools-40.6.3-py2.py3-none-any.whl
Collecting wheel
  Using cached https://files.pythonhosted.org/packages/ff/47/1dfa4795e24fd6f93d5d58602dd716c3f101cfd5a77cd9acbe519b44a0a9/wheel-0.32.3-py2.py3-none-any.whl
launchpadlib 1.10.6 requires testresources, which is not installed.
Installing collected packages: pip, setuptools, wheel
  The script wheel is installed in '/home/ubuntu/.local/bin' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed pip-18.1 setuptools-40.6.3 wheel-0.32.3
```

pathを通しました。

```bash
$ echo 'export PATH=$PATH:$HOME/.local/bin' >> ~/.bashrc
$ source ~/.bashrc
```

python3.7向けにpipが入りました。

```bash
$ pip3.7 -V
pip 18.1 from /home/ubuntu/.local/lib/python3.7/site-packages/pip (python 3.7)
```

## pipenvのインストール

```bash
$ pip3.7 install --user pipenv
```

* 参考: https://pipenv-ja.readthedocs.io/ja/translate-ja/install.html#installing-pipenv

```bash
$ pipenv --version
pipenv, version 2018.11.26
```

入りました。

## 動作確認

これで、python3.7, pip, pipenvがインストールできました。
仮想環境を作ってみましょう。

```bash
$ pipenv install --python 3.7 numpy pandas matplotlib jupyterlab
$ pipenv shell
$ python -c "import sys; print(sys.version)"
3.7.1 (default, Oct 22 2018, 11:21:55) 
[GCC 8.2.0]
$ python -c "import pandas; print(pandas.__version__)"
0.23.4
```

出来ました。以上です。