こんにちは。バックエンドエンジニア / SRE のまのめです。
先日、弊社のテスト環境「 tako 環境 」が焼けなくなり(*)、それについて調査・解決したことをまとめました。
* tako 環境を焼く = 社内用語で、テスト環境を作成/更新すること
状況
python3.5 で動くアプリケーションの tako 環境 を焼く際、 ansible のタスクが失敗するようになりました。
ansible のログを追うと、以下のようなエラーが出力されていました。
ERROR: You need Python 2.7 or 3.4 to install the typing package. ---------------------------------------- :stderr: Command \"python setup.py egg_info\" failed with error code 1 in /tmp/pip-buikd-XXXXXX/typing You are using pip version 7.1.2, however version 20.1.1 is available. You should consider upgrading via the 'pip install --upgrade pip' command.
複数回、複数環境で試したのですが、どうやら Flask-Injector
の pip install ができなくなっており、 typing
というモジュールの install でコケているようでした。
原因
先程も述べたように、アプリケーションは python3.5 系で動いています。
このアプリケーションで Flask-Injector
を利用していますが、ある程度歴史もあるため若干バージョンが古めでした。
また、この現象が起きたのが 2020 年 7 月 10 日 で、 typing
モジュールはその日にアップデートがありました。
ここで、typing
モジュールの このときの最新版(3.7.4.2)の Project description に新しくこんな注意が記載されていました。
For package maintainers, it is preferred to use typing;python_version<"3.5" if your package requires it to support earlier Python versions. This will avoid shadowing the stdlib typing module when your package is installed via pip install -t . on Python 3.5 or later.
さらに、 Flask-Injector
の該当バージョンのモジュールの requirements を見たら、以下のようになっていました。
install_requires=['Flask', 'injector>=0.10.0', 'typing'],
flask_injector/setup.py at v0.10.1
はい、 Flask-Injector
のこのバージョンでは、 typing
のバージョンが固定されていませんね。
つまり、
Flask-Injector
で typing
のバージョンが固定されていないために最新版が入る
=> typing
の最新版は python3.5 で入れられなくなった
=> pip install がコケる
ということだったのです。
そして解決へ
typing
のバージョンをこちらが定義する requirements で無理やり固定してもよいのですが、ほかのモジュールでまたこういう事があると面倒だな…と思っていました。
そこで試しに、 pip install --upgrade pip setuptools
をしたら、直りました。
このとき急いでいたこともあり、なぜそれで解決するのかを詳しく調べませんでしたが、おそらく setuptools がいい感じに働いてくれるのだと予想されます。 なので、 pip install する直前に setuptools をアップグレードするように ansible のタスクを修正し、 tako 環境 は無事直りました。
感想
こういったモジュールが古くて起こる不具合には、今回のようにその場しのぎな解決ではなく、根本的な解決であるモジュールのアップグレードで対応したいです。
しかし、緊急性が高い場合はひとまず今回のように処理し、時間をかけてモジュールのアップグレードの検証を進めて、根本解決できるといいなと思いました。
サービスが大きくなっていくとなかなかモジュールのバージョンにまで目を向けられなくなっていきますが、こういうことが本番で起きる前に、定期的に振り返る時間を作っておきたいですね。