WSL2（Ubuntu） + Pyenv でPython開発環境（Pipenv / Poetry）

# 環境

- Windows 11
- WSL2（Ubuntu 22.04.2）

# VS Code のインストール

公式ページよりインストーラーをダウンロードし、Windows側にインストールします。

[Visual Studio Code - Code Editing. Redefined](https://code.visualstudio.com/)

インストール後、VS Code を起動し、画面左の「拡張機能」パネルにて以下の拡張機能をインストールします。

|名前|識別子|内容|
|---|---|---|
|Python|ms-python.python|VS Code用Python拡張機能|
|Pylance|ms-python.vscode-pylance|Python言語サーバー|


# WSLの設定

- Windows側のPATH設定の引き継ぎ解除
- VS Codeのエイリアス追加
を行います。

WSL - Ubuntu のターミナルを開き、以下を実行します。

```shell:Ubuntu - WSLの設定
echo 'alias code="'`which code`'"' >> ~/.bashrc
cat /etc/wsl.conf >> ~/wsl.conf.tmp
echo '[interop]' >> ~/wsl.conf.tmp
echo 'appendWindowsPath = false' >> ~/wsl.conf.tmp
sudo mv ~/wsl.conf.tmp /etc/wsl.conf
sudo chown root:root /etc/wsl.conf
```

WSL2 ではデフォルトで Windows側の PATH が引き継がれます。
`python`コマンドなど、Windows側のコマンドが使用されるとうまく動作しないので、
PATH が引き継がれないように設定を変更しています。
また、PATH設定の引き継ぎ解除により、Windows側の VS Code への PATH が通っていない状態になるため、
エイリアスを追加しています。

上記コマンドにより、以下の通り各ファイルに追記が行われています。

```/etc/wsl.conf
[interop]
appendWindowsPath = false
```

```~/.bashrc
alias code='"/mnt/c/Program Files/Microsoft VS Code/bin/code"'
```

設定を反映するため、WSL を再起動します。
*Windows側のターミナル*を開き、以下を実行します。

```shell:Windows - WSLの停止
wsl --shutdown
```

再度、WSL - Ubuntu のターミナルを開き、VS Code コマンドのエイリアス設定を確認します。

```shell:VS Codeのエイリアス設定確認
command -v code
# -> alias code='"/mnt/[VS Codeのパス]"'
```

# Python（Pyenv）のインストール

Python については WSL - Ubuntu に既にインストールされていたりもしますが、
プロジェクトごとにPythonのバージョンを切り替えて使用することが難しいです。
Pyenv を使用することで、複数のバージョンをインストールし、切り替えて使用することが可能となります。

[pyenv/pyenv: Simple Python version management](https://github.com/pyenv/pyenv)

上記ページのインストール手順に従い、以降のコマンドを実行し、Pyenv のインストールを行います。

```shell
# 依存パッケージのインストール
sudo apt update
sudo apt install build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev curl \
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev

# Pyenv のインストール
curl https://pyenv.run | bash

# 環境変数等の設定
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
source ~/.bashrc
```

参考：
- 依存パッケージのインストール  
  [Home · pyenv/pyenv Wiki - Suggested build environment](https://github.com/pyenv/pyenv/wiki#suggested-build-environment)
- Pyenv のインストール  
  [pyenv/pyenv: Simple Python version management - Automatic installer](https://github.com/pyenv/pyenv#automatic-installer)

実行後、以下にてインストールを確認します。

```shell
pyenv --version
# -> pyenv X.X.X
```

## Pyenv による Python のインストール

Pyenv にて任意のバージョンの Python をインストールできますが、
ここでは、`3.10.11` をインストールすることとします。

```shell
pyenv install 3.10.11
pyenv global 3.10.11
python --version
# -> Python 3.10.11
```

Pyenv の使用方法の詳細については省きますが、主なコマンドは以下の通りです。

|コマンド|内容|
|---|---|
|pyenv install --list|インストール可能な Python のバージョン一覧を表示|
|pyenv install [任意のPythonのバージョン]|特定バージョンのPythonのインストール|
|pyenv global [任意のPythonのバージョン]|特定バージョンのPythonをグローバル設定として指定|

---

# パッケージ管理ツールを使用した開発環境構築

Python のパッケージ管理ツールはいくつかあるかと思いますが、
以降、代表的な２つのツールを使用した構築方法について記載します。

- Pipenv
- Poetry

# Pipenv の場合

## Pipenv のインストール

以下のコマンドにて、インストールを行います。

```shell
pip install pipenv

# プロジェクト配下にPython仮想環境を作成するように環境変数を設定
echo 'export PIPENV_VENV_IN_PROJECT=1' >> ~/.bashrc
source .bashrc
```

下段の環境変数設定について。
Pipenv はデフォルトでは `~/.local/share/virtualenvs/` 配下に仮想環境を作成しますが、
環境変数 `PIPENV_VENV_IN_PROJECT` を設定することでプロジェクト配下に仮想環境を作成するようになります。

## 仮想環境作成

任意のディレクトリ（ここでは`pipenvtest`とします）を作成し、Python仮想環境を作成します。

```shell
mkdir pipenvtest
cd pipenvtest/
pipenv --python 3.10
```

上記を実行すると、`.venv`ディレクトリが追加され、Python仮想環境が作成されます。
他の Pythonバージョンを使用する場合は、`pyenv install [Pythonバージョン]`にて Python をインストールした後に、
`pipenv --python X.X` でバージョンを指定します。

## 開発用パッケージのインストール

コードフォーマッター、Lint関連の以下のパッケージをインストールします。

- black
- flake8
- mypy

```shell
pipenv install black flake8 mypy --dev
```

## VSCode の起動と初期設定

以下のコマンドにて、VS Code を起動します。

```shell
code .
```

### 拡張機能のインストール

起動後、画面左の「拡張機能」パネルにて、以下の拡張機能をインストールします。

- Python
- Pylance

Windows側の VS Code に上記拡張機能がインストール済みであれば、
一覧上に表示されるので、`WSL: Ubuntu・・・  にインストール` をクリックすることで、
WSL側へのインストールが行われます。

![拡張機能インストール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114386/82b409e1-a42c-4702-4a46-6a179b62a9e2.png)

### VSCodeの設定

コードフォーマッター、Lint関連を有効にするため、
`.vscode/settings.json` を作成し、以下をコピペしてください。

```text:.vscode/settings.json
{
  "python.analysis.completeFunctionParens": true,
  "python.formatting.provider": "black",
  "python.languageServer": "Pylance",
  "python.linting.flake8Args": ["--max-line-length=88"],
  "python.linting.flake8Enabled": true,
  "python.linting.mypyEnabled": true,
  "python.linting.pylintEnabled": false,
  "python.terminal.activateEnvInCurrentTerminal": true
}
```

また、プロジェクトディレクトリ直下に `.env` を作成し、以下をコピペしてください。

```text:.env
PYTHONPATH=${PYTHONPATH};.
```

上記を行うことで、実行時にプロジェクト配下のソースファイルのインポートが行われるようになります。

### サンプルプログラムの作成

以降、動作確認のためのサンプルプログラムになります。

サンプルプログラム用のパッケージ追加を行います。

```shell
pipenv install numpy matplotlib
```

プロジェクト直下に `test.py` を作成し、以下をコピペしてください。

```python:test.py
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-np.pi, np.pi)
y = np.sin(x)
plt.plot(x, y)
plt.show()
```

ここまでの設定がうまくいっていれば、
画面右下の Python 環境の表示で、作成した仮想環境が選択されていると思います。

![Python仮想環境選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114386/bcecb790-952d-6f14-3d38-aa460fdc6dba.png)

また、ドキュメントの表示やコード補完、フォーマッター、Lint が効くはずです。

![ドキュメント表示.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114386/fc417848-9e41-9909-2c4c-33a7afdbb41e.png)
![コード補完.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114386/eecd28d3-60c5-b33c-4646-5266b1c99ec4.png)

### サンプルプログラムの実行

`test.py` を開いた状態で、「実行」パネルを開き、
「launch.json ファイルを作成します」→ 「Python File」と選択します。

![実行.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114386/5b75b050-3705-25a6-75a6-041e6c339458.png)

`vscode/launch.json` が作成され、Python用の実行構成が設定されます。

![実行構成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114386/e31fa5ac-b5a4-1837-7404-d750616de45b.png)

```json:.vscode/launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: 現在のファイル",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal",
            "justMyCode": true
        }
    ]
}
```

再度、`test.py` を開いた状態で、F5キーを押下するか
「実行」パネルで「Python: 現在のファイル」を選択して実行ボタンをクリックすることで、実行されます。

このサンプルプログラムでは以下のようなグラフが表示されます。

![実行結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114386/2d31e13a-e2fe-02c7-88b8-3521a6b272f8.png)

# Poetry の場合

## Poetry のインストール

以下のコマンドにて、インストールを行います。

```shell
curl -sSL https://install.python-poetry.org | python -

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

# プロジェクト配下にPython仮想環境を作成するように設定を追加
poetry config virtualenvs.in-project true
```

下段の設定追加については、Pipenv の場合の `PIPENV_VENV_IN_PROJECT` と同様に、
設定することでプロジェクト配下に仮想環境を作成するようになります。

## 仮想環境作成

任意のディレクトリ（ここでは`poetrytest`とします）を作成し、Python仮想環境を作成します。

```shell
mkdir poetrytest
cd poetrytest/
poetry init
```

以降のように対話形式となり、基本的に Enter 連打のデフォルト設定でよいですが、
`Author [None, n to skip]:` のところだけ、`n` の入力が必要でした。

```text
Package name [poetrytest]:
Version [0.1.0]:
Description []:
Author [None, n to skip]:  n
License []:
Compatible Python versions [^3.10]:

Would you like to define your main dependencies interactively? (yes/no) [yes]

（中略）

Package to add or search for (leave blank to skip):

Would you like to define your development dependencies interactively? (yes/no) [yes]
Package to add or search for (leave blank to skip):

Generated file

（中略）

Do you confirm generation? (yes/no) [yes]
```

上記の実行で、Pipenv の場合と同様に `.venv` にPython仮想環境が作成されます。

## 以降

以降は Pipenv と同様の手順になりますが、
パッケージインストールのみ、以下のように `poetry add` コマンドを使用することになります。

```shell
poetry add black flake8 mypy --dev
poetry add numpy matplotlib
```