はじめに
ちくせい花火大会のコラボスターマイン、めっちゃきれいでした... アーカイブで見たnikkieです。
ここ数日、SpeechRecognitionでdistutilsを使っている箇所の置き換えを進めていました。
目次
distutils
この記事で初めてdistutilsを聞いたという方は、覚える必要はありません!1
なぜなら、Python 3.12で標準ライブラリから削除されたからです🎉
https://packaging.python.org/en/latest/key_projects/#distutils より
The original Python packaging system, added to the standard library in Python 2.0 and removed in 3.12.
distutils は 非推奨で、Python 3.12 での除去が予定されています。
What's New In Python 3.12 — Python 3.13.0 ドキュメントより
PEP 632: Remove the distutils package.
この記事を書く中で削除のPEPもあったことを知りました。
SpeechRecognitionとdistutils
発端はこちらのIssue
メンテナの言い分として、今回のリリースの前のSpeechRecognitionは、Python 3.8〜3.11までしかサポートしていません2。
3.12でインストールできないのはサポートしていないのだから当然で、feature requestという認識でした。
issueではdistutilsをコードに残した状態で解決するworkaroundが挙がっています3。
このたび根本的な対応をした次第です
distutilsを使っている箇所は2箇所でした
$ git checkout 3.10.4 $ git grep distutils setup.py:from distutils import log speech_recognition/__init__.py: from distutils.version import LooseVersion
1️⃣ distutils.logを削除
loggingモジュールを使ったロギングに置き換えました4。
該当箇所
# https://github.com/Uberi/speech_recognition/blob/3.10.4/setup.py#L8 from distutils import log # https://github.com/Uberi/speech_recognition/blob/3.10.4/setup.py#L22 log.info("setting executable permissions on {}".format(output_path))
distutils.logは「Simple PEP 282-style logging」とだけあります。
https://docs.python.org/3.11/distutils/apiref.html#module-distutils.log
実装を見たところ、loggingモジュールは使わずに、loggingモジュール相当のロギングを実装しているようでした。
https://github.com/python/cpython/blob/v3.11.10/Lib/distutils/log.py
ルートロガーではなく子ロガーを作って、INFOログを出力するように置き換えました。
(でも元々から含めて、デフォルトのログレベルWARNINGを変えていなさそうで、INFOレベルのログって出力されるのかちょっと疑問です)
2️⃣ distutils.versionを削除
PEP 632の「Migration Advice」によれば、packagingへの置き換えとなります5。
ですが、今回は単に削除しました
該当箇所
https://github.com/Uberi/speech_recognition/blob/3.10.4/speech_recognition/__init__.py#L111-L113
from distutils.version import LooseVersion if LooseVersion(pyaudio.__version__) < LooseVersion("0.2.11"): raise AttributeError("PyAudio 0.2.11 or later is required (found version {})".format(pyaudio.__version__))
distutils.versionには、バージョン番号を表す2つのクラスStrictVersionとLooseVersionがあります。
https://github.com/python/cpython/blob/v3.11.10/Lib/distutils/version.py
SpeechRecognitionはPyAudio6 0.2.11以降をインストールしてほしいので、LooseVersionでバージョンチェックをしています。
私の意見は、「ここにバージョンチェックの責務をもたせなくてもよいのではないか」というものです。
パッケージのmetadataの記載を工夫してPyAudio 0.2.11以降がインストールできるように担保できると考え、今回は削除しました。
pip install SpeechRecognition[audio]とインストールしたときに、PyAudio 0.2.11以降がインストールされるようにextraを書いています。
https://github.com/Uberi/speech_recognition/blob/3.11.0/setup.cfg#L10-L11
[options.extras_require] audio = PyAudio >= 0.2.11
終わりに
Python 3.12で削除されたdistutilsをSpeechRecognitionから除きました。
これによりSpeechRecognition 3.11.0はPython 3.12をサポートできています!
distutils、これまでの長い年月、Pythonのパッケージングを支えてくれてありがとう。
手元のPython 3.12の環境にpip install SpeechRecognitionできることを確認しています。
お手元でうまく動かない場合はissueを立てるなどでお知らせください
スターやスポンサーでメンテナ活動を支えていただけるととっても嬉しいです!
- distutilsのドキュメントには「setuptools は distutils の改良された代替品」とあります。setuptoolsの名前を覚えておくといいかもしれません↩
- 「分類」の「Programming Language」をご覧ください:https://pypi.org/project/SpeechRecognition/3.10.4/↩
- よくまとまっている 「What's New In Python 3.12」に「The third-party Setuptools package continues to provide distutils, if you still require it in Python 3.12 and beyond.」とあるので、ここの方法でうまくいくのかなと認識してます↩
- logging? まかせて!! ↩
- ばんくしさんのご本で見たやつ!!(バージョンの扱いが簡単そうでした) ↩
- マイクを使う場合に追加でインストールしてほしいパッケージです↩