Ubuntu 20.04 LTSでpython3.6 pipを動かす

## はじめに

Ubuntu 20.04ではデフォルトのpythonが3.8になりました。Python3.6は入っていますがpipが動きません。Python3.8ではインストールできないライブラリがまだあるため、python3.6でもpipを使えるようにしてみました。Python3.6とpip3.6を使えるようにする方法として、pyenvを使う、ソースをビルドする方法もあると思いますが、既に入っているpython3.6を活用する方法を試してみました。

## Ubuntu 20.04のpython3.6でpipを動かすとどうなるか

Ubuntu 20.04には以下のようにpython 3.6が入っています。

```
$ cat /etc/os-release 
NAME="Ubuntu"
VERSION="20.04 LTS (Focal Fossa)"

$ python3.6 --version
Python 3.6.7
```

しかしpipを動かすと以下のようにエラーになってしまい、ライブラリの追加インストールができません。

```
$ python3.6 -m pip list
Traceback (most recent call last):
  File "/usr/lib/python3.6/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
　  　　・
　　　(中略）
　　　　・
ModuleNotFoundError: No module named 'distutils.util'
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
 　　 　・
　　　(中略）
　　　　・
ModuleNotFoundError: No module named 'apt_pkg'

Original exception was:
Traceback (most recent call last):
  File "/usr/lib/python3.6/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
　　  　・
　　　(中略）
　　　　・
ModuleNotFoundError: No module named 'distutils.util'
```

エラーメッセージを見ると、<font color="red">'distutils.util'</font>と<font color="red">'apt_pkg'</font>が見つからないと言っています。distutils は python 標準のパッケージ管理ツールです。そのため、pipが動かないことに関係がありそうです。

## distutilsを調べる

distutilsのaptパッケージをインストールしようとすると、既にpython3.8用がインストール済です。

```
$ sudo apt install python3-distutils  
Reading package lists... Done
Building dependency tree       
Reading state information... Done
python3-distutils is already the newest version (3.8.2-1ubuntu1).
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
```

Python3.6用のdistutilsが入るディレクトリは殆ど空の状態です。

```
$ ll /usr/lib/python3.6/distutils/
total 44
drwxr-xr-x  2 root root  4096  5月 22 19:50 ./
drwxr-xr-x 29 root root 20480  3月 28 20:06 ../
-rw-r--r--  1 root root   236 10月 22  2018 __init__.py
-rw-r--r--  1 root root 12345 10月 22  2018 version.py
```

## Python3.6-distutilsのdebパッケージをダウンロードしてファイルをコピーする

python3-distutils_3.6.5-3_all.debをダウンロードして適当なディレクトリに展開して中身を確認。

```
$ wget http://archive.ubuntu.com/ubuntu/pool/main/p/python3-stdlib-extensions/python3-distutils_3.6.5-3_all.deb

$ dpkg -x python3-distutils_3.6.5-3_all.deb ./python3-distutils_3.6

$ ll ./python3-distutils_3.6/usr/lib/python3.6/distutils/
total 460
drwxr-xr-x 3 kenshi kenshi  4096  4月  4  2018 ./
drwxr-xr-x 3 kenshi kenshi  4096  4月  4  2018 ../
-rw-r--r-- 2 kenshi kenshi  8121  4月  4  2018 archive_util.py
-rw-r--r-- 2 kenshi kenshi 14935  4月  4  2018 bcppcompiler.py
-rw-r--r-- 2 kenshi kenshi 47415  4月  4  2018 ccompiler.py
-rw-r--r-- 1 kenshi kenshi 19129  4月  4  2018 cmd.py
　　  　・
　　　(中略）
　　　　・
-rw-r--r-- 1 kenshi kenshi 20789  4月  4  2018 util.py
-rw-r--r-- 2 kenshi kenshi  5133  4月  4  2018 versionpredicate.py
```

それっぽいファイルが入っていそうです。このファイルを直接/usr/lib/python3.6/distutils/に展開してやります。以下のようにdebファイルを/(ルート)に展開してやると所定のディレクトリにファイルが書き込まれます。

```
$ sudo dpkg -x python3-distutils_3.6.5-3_all.deb /

$ ll /usr/lib/python3.6/distutils/
total 496
drwxr-xr-x  3 root root  4096  4月  4  2018 ./
drwxr-xr-x 29 root root 20480  4月  4  2018 ../
-rw-r--r--  2 root root  8121  4月  4  2018 archive_util.py
-rw-r--r--  2 root root 14935  4月  4  2018 bcppcompiler.py
-rw-r--r--  2 root root 47415  4月  4  2018 ccompiler.py
-rw-r--r--  1 root root 19129  4月  4  2018 cmd.py
　　  　・
　　　(中略）
　　　　・
-rw-r--r--  1 root root 20789  4月  4  2018 util.py
-rw-r--r--  2 root root  5133  4月  4  2018 versionpredicate.py
-rw-r--r--  1 root root 12345 10月 22  2018 version.py
```

## apt_pkgを認識できるようにする

apt_pkg.cpython-37m-x86_64-linux-gnu.soのシンボリックリンクが何やら変です。

```
$ ll /usr/lib/python3/dist-packages/apt_pkg*.so
lrwxrwxrwx 1 root root     39  4月 28 21:43 apt_pkg.cpython-36m-x86_64-linux-gnu.so -> apt_pkg.cpython-37m-x86_64-linux-gnu.so
-rw-r--r-- 1 root root 359376  4月  9 16:16 apt_pkg.cpython-38-x86_64-linux-gnu.so
```

シンボリックリンクを以下のように修正。

```
$ sudo unlink ./apt_pkg.cpython-36m-x86_64-linux-gnu.so 
$ sudo ln -s /usr/lib/python3/dist-packages/apt_pkg.cpython-38-x86_64-linux-gnu.so apt_pkg.so
```

## 動作確認

```
$ python3.6 -m pip list
Package                 Version       
----------------------- --------------
apturl                  0.5.2         
asn1crypto              0.24.0        
bcrypt                  3.1.7         
blinker                 1.4           
Brlapi                  0.7.0         
certifi                 2019.11.28    
chardet                 3.0.4         
　　  　・
　　　(中略）
　　　　・
ufw                     0.36          
unattended-upgrades     0.1           
urllib3                 1.25.8        
usb-creator             0.3.7         
wadllib                 1.3.3         
wheel                   0.34.2        
xkit                    0.0.0         
zope.interface          4.7.1 
```

キター！！、動きました😆✌️

ライブラリのインストールもできました。

```
$ python3.6 -m pip install numpy
Collecting numpy
  Downloading numpy-1.18.4-cp36-cp36m-manylinux1_x86_64.whl (20.2 MB)
     |████████████████████████████████| 20.2 MB 4.5 MB/s 
Installing collected packages: numpy
Successfully installed numpy-1.18.4

$ python3.6
Python 3.6.7 (default, Oct 22 2018, 11:32:17) 
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 
>>> import sys
>>> 
>>> sys.path
['', '/usr/lib/python36.zip', '/usr/lib/python3.6', '/usr/lib/python3.6/lib-dynload', '/home/kenshi/.local/lib/python3.6/site-packages', '/usr/local/lib/python3.6/dist-packages', '/usr/lib/python3/dist-packages']
>>> 
>>> import numpy
```

ライブラリのパスも正しく認識しているようです。

ちょっと強引なやり方かも知れませんが、この方法でインストールした、tensorflow 1.15.0とpytorch 1.3.0が、単純なモデルではありますがGPUモードで動いています。pytorchは、python3.8のpipだと1.4以降しかインストールできないため、旧バージョンを使うためにpython3.6のpipが動くと重宝します。

## 残課題

ただ問題もあり、boostを使ってCのライブラリを呼び出すようなpythonライブラリはインストールできません。そのため、pycudaはpipだけでなく、ソースからのインストールもできませんでした。boostのライブラリがpython3.8に紐ついているようで、これはうまくいかず。