Ubuntu20.04にpyenvを使ってPython開発環境を構築するまで

## Python環境セットアップ

Python流行ってますね。

Pythonは最近になって大人気になりましたが、生まれはとても古く、JavaやPHPよりも先輩です。古い言語なので最近の主流を取り込めていなかったり、セットアップが面倒だったりするので、そのあたりを整理してみようと思います。

またPythonにもたくさんのパッケージがありますが、新しいバージョンだと動かなかったり、開発で急遽古いバージョンのPythonが必要になったりするときがあります。
こういうときに便利なのがxxenv系のpyenvです。

ただ、pyenvはPythonのコードを落としてビルドするため、OSのライブラリをいくつか必要とします。
また一部ライブラリがなくてもPythonのビルド自体は成功するのですが、pipコマンドでモジュールインストールするときに、ライブラリなしでビルドしたためエラーになることがあります。最低限のライブラリがどれなのか絞って記しておこうと思います。

また折角なのでpoetryを使って、Linter/Formatterの設定までした開発環境を構築するところまで手順を記しておこうとおもいます。

### Ubuntu20.04インストール直後

OSインストール直後のおまじないです。
とりあえず再起動しておきましょう。

```bash
sudo apt update && sudo apt upgrade
sudo reboot
```

## Pythonビルドに必要なライブラリインストール

必要なライブラリは以下の通りです。

```bash
sudo apt install -y git build-essential libssl-dev libbz2-dev libreadline-dev libsqlite3-dev zlib1g-dev libffi-dev
```

## パッケージごとに必要なライブラリ

pip installするパッケージによっては、別途に必要にライブラリもあります。
これらパッケージはPythonのビルド後のインストールでも問題ないので適宜追加しましょう

### mecabをインストールする場合

```bash
sudo apt install mecab libmecab-dev
```

### mysqlclientをインストールする場合

```bash
sudo apt install mysql-client libmysqlclient-dev
```

## pyenvセットアップ

ほぼ、公式ページ通りです。pyenvコマンドを使えるようにセットアップしましょう。

https://github.com/pyenv/pyenv

```bash
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n  eval "$(pyenv init -)"\nfi' >> ~/.bashrc
exec "$SHELL"
```

### pythonビルド&インストール

pyenvを使ってPython3.8.6をインストールしてみます。
`pyenv install 3.8.6` でソースコードからPythonをビルドするため、それなりに時間がかかります。
最後にglobalとrehashも忘れないようにしましょう。このあたりも公式ページ通りです。

```bash
pyenv install 3.8.6
pyenv global 3.8.6
pyenv rehash
```

以上でPythonの環境セットアップは完了です。


## 開発プロジェクトセットアップ



### pipアップデートとpoetryインストール

Pythonのインストールが完了し、PATHが通ったので、pipコマンドが使用できます。

pipコマンドは、npmで例えると、常時`npm i -g`状態です。つまりグローバルな環境にパッケージがインストールされます。開発プロジェクトごとに使用するパッケージを分けるのが昨今の常識なのでpoetryをつかいます。

poetry以外にもpipenvというツールもあります。pypa管轄のツールになったのでこちらが主流なのかもしれないですが開発が滞りがちです。。依存関係の解決が遅いのが欠点です。

一方でpoetryは、PEP 518で提案されたpyproject.tomlを使用してパッケージ管理を行います。pythonの標準に従っており、開発も盛んです。

どちらが覇権をとるかは未だにわかりませんが、私はpoetryを使っています。

```bash
pip install -U pip
pip install poetry
```

### プロジェクトのディレクトリ作成

```bash
mkdir hellopy && cd hellopy
git init
poetry init
```

`poetry init`するとインタラクティブな画面になりますので、とりあえずここでは適当に入力していきます。パッケージインストールは後でまとめて行うので**no**にしておきます。

[![Image from Gyazo](https://i.gyazo.com/00b317cef50853b38a3ca30f8a836e07.png)](https://gyazo.com/00b317cef50853b38a3ca30f8a836e07)


### linter & formatter

自分が必ず使用するPythonのlinter/formatterをインストールしておきます。

またgit commit時にこれらlinter/formatterを自動実行するためにpre-commitもいれておきます。

これらは開発用ツールなのでdevDependencyになります。

- Linter: flake8 mypy
- Formatter: black isort

``` bash
poetry add -D flake8 mypy black isort pre-commit
```

#### pre-commit

こちらpre-commitの設定ファイルです
下記の`.pre-commit-config.yaml`をhellopy下に作成して、以下のコマンドを実行しましょう。

これで開発環境は一通り完成です。

```bash
pre-commit install
pre-commit
```

```yaml　.pre-commit-config.yaml
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v2.3.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-json
      - id: flake8
      - id: check-yaml
        # - repo: https://github.com/asottile/seed-isort-config
        #   rev: v1.9.3
        #   hooks:
        #     - id: seed-isort-config
  - repo: https://github.com/pre-commit/mirrors-isort
    rev: v4.3.21
    hooks:
      - id: isort
  - repo: https://github.com/psf/black
    rev: 19.10b0
    hooks:
      - id: black
  - repo: https://github.com/pre-commit/mirrors-mypy
    rev: "v0.740" # Use the sha / tag you want to point at
    hooks:
      - id: mypy
        additional_dependencies: [sqlalchemy-stubs]
```

## 終わりに

なんどか苦戦したので、改めてまとめてみたのですが、意外とシンプルでした。個人的に開発環境セットアップが一番難しいと思う言語はPHPです。phpenvを使うと色々な地獄をみれます。OSベッタリな言語ほど環境構築に苦戦する印象です。

Pythonもいまのブームに乗ってNode.jsくらいシンプルになると良いですね。

というわけで解説は以上になります。よいPythonライフを。