[python][pip]pipでインストールしたパッケージのコンフリクトを解消する

DjangoでWebアプリケーション開発をしようと思い、そのための開発環境をDocker+VSCode RemoteDevelopmentで構築しようとしたときのこと。

コードの自動整形を行って欲しいと思ったので、flake8(リンター、つまりPythonソースコードの論理エラーやスタイルをチェックするもの) と autopep8(フォーマッター、つまりPythonコードをコーディング規約に沿って自動修正してくれるもの) を用いることに。そのため、Dockerfileに

FROM python:3.6
## 省略
RUN pip3 install flake8
RUN pip3 install autopep8
## 省略

と記述してこれらをインストール。VSCode側の設定も行ったが、自動整形が行われない……。

これは依存関係に衝突が起こっているかも?と思ったので、pip check を実行して、パッケージの依存関係で問題のあるものを調べる。すると……。

$ pip check
flake8 5.0.4 has requirement pycodestyle<2.10.0,>=2.9.0, but you have pycodestyle 2.10.0.

案の定、パッケージが衝突しているようだ……。

ちょっと見にくく感じるがエラーコードを読む限り、pycodestyleのパッケージは、2.9.0以上、2.10.0未満である必要があるが、ぼくのpycodestyleのパッケージは2.10.0になっている模様。

flake8もautopep8は最新のバージョンのものだが、flake8がautopep8の依存関係でインストールされたバージョンのpycodestyleに対応していないっぽい。

最新版が更新されるまで待ってからアップデートするのでも良いが、今使いたいのでここはpycodestyleのバージョンを下げて対応しよう!

$ pip install pycodestyle==2.9.0
Collecting pycodestyle==2.9.0
  Downloading pycodestyle-2.9.0-py2.py3-none-any.whl (41 kB)
     |████████████████████████████████| 41 kB 736 kB/s             
Installing collected packages: pycodestyle
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
autopep8 2.0.2 requires pycodestyle>=2.10.0, but you have pycodestyle 2.9.0 which is incompatible.
Successfully installed pycodestyle-2.9.0

エラー出たわ……。

“ERROR: pip’s dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
autopep8 2.0.2 requires pycodestyle>=2.10.0, but you have pycodestyle 2.9.0 which is incompatible.” って言われているので、autopep8はpycodestyleの2.10.0以上欲しいのに、2.9.0しかない!って怒られてるようだ。

実際にpip checkを再び実行すると……。

$ pip check
autopep8 2.0.2 has requirement pycodestyle>=2.10.0, but you have pycodestyle 2.9.0.

先程のエラーと同様、autopep8の2.0.2のバージョンだとpycodestyleが2.10.0以上欲しい!とのこと。

こうなったら、autopep8のバージョンの方を下げて対応するしかないな。

下げるバージョンを探すには、Python Package Indexがおすすめだ。

パッケージ名で検索し、左側のタブの「リリース履歴」をクリックすれば、どのバージョンが存在するかを見ることができる。

今回はautopep8の2.0.0を選択。これをインストールする。

$ pip install autopep8==2.0.0
Collecting autopep8==2.0.0
  Downloading autopep8-2.0.0-py2.py3-none-any.whl (45 kB)
     |████████████████████████████████| 45 kB 2.1 MB/s             
Requirement already satisfied: tomli in /usr/local/lib/python3.6/site-packages (from autopep8==2.0.0) (1.2.3)
Requirement already satisfied: pycodestyle>=2.9.1 in /usr/local/lib/python3.6/site-packages (from autopep8==2.0.0) (2.10.0)
Installing collected packages: autopep8
  Attempting uninstall: autopep8
    Found existing installation: autopep8 2.0.2
    Uninstalling autopep8-2.0.2:
      Successfully uninstalled autopep8-2.0.2
Successfully installed autopep8-2.0.0

pipではバージョン指定してinstallすれば、既にインストールしていたバージョンをアンインストールして、新しいバージョンをインストールしてくれる。こんかいであれば、autopep8の2.0.2をアンインストールして、autopep8の2.0.0をインストールしてくれる。

ただ、このままではまだ依存関係は解決していない。flake8の5.0.4と、autopep8の2.0.0の両方に対応したバージョンのpycodestyleをインストールしなおす必要がある。

$ pip install pycodestyle==2.9.1
Collecting pycodestyle==2.9.1
  Using cached pycodestyle-2.9.1-py2.py3-none-any.whl (41 kB)
Installing collected packages: pycodestyle
  Attempting uninstall: pycodestyle
    Found existing installation: pycodestyle 2.10.0
    Uninstalling pycodestyle-2.10.0:
      Successfully uninstalled pycodestyle-2.10.0
Successfully installed pycodestyle-2.9.1

あとは依存関係のチェック。

$ pip check
No broken requirements found.

依存関係が解消!

これで自動整形も動くようになった。

余談だが、パッケージ依存関係のチェックは、”pip check”以外にも、”pipdeptree”も存在する。こちらはpipなどで追加でインストールすることが必要になるが、より詳しく表示してくれる。

$ pipdeptree 
Warning!!! Possibly conflicting dependencies found:
* flake8==5.0.4
 - pycodestyle [required: >=2.9.0,<2.10.0, installed: 2.10.0]
------------------------------------------------------------------------
autopep8==2.0.2
  - pycodestyle [required: >=2.10.0, installed: 2.10.0]
  - tomli [required: Any, installed: 1.2.3]
Django==3.2.20
  - asgiref [required: >=3.3.2,<4, installed: 3.4.1]
    - typing-extensions [required: Any, installed: 4.1.1]
  - pytz [required: Any, installed: 2023.3]
  - sqlparse [required: >=0.2.2, installed: 0.4.4]
flake8==5.0.4
  - importlib-metadata [required: >=1.1.0,<4.3, installed: 4.2.0]
    - typing-extensions [required: >=3.6.4, installed: 4.1.1]
    - zipp [required: >=0.5, installed: 3.6.0]
  - mccabe [required: >=0.7.0,<0.8.0, installed: 0.7.0]
  - pycodestyle [required: >=2.9.0,<2.10.0, installed: 2.10.0]
  - pyflakes [required: >=2.5.0,<2.6.0, installed: 2.5.0]
mysqlclient==2.1.1
numpy==1.19.5
pipdeptree==2.2.1
  - pip [required: >=6.0.0, installed: 21.3.1]
PyMySQL==1.0.2
setuptools==57.5.0
wheel==0.37.0

pythonで色々なプロジェクトでパッケージを管理しようとすると、今回のように依存関係でコンフリクトが起きるので、仮想環境で環境構築するのは大事だなぁと痛感した。

Dockerは偉大……。

ではでは~

コメント

タイトルとURLをコピーしました