public note

PyCon APAC 2023 Day1 で ModuleNotFoundError に関する発表をしました

参加記はまた別で書きます。

会場では 30 名くらい?の方々が聴きにきてくれました。ありがとうございます。

発表したこと

タイトル

2023/10/27 16:20 ~ 16:35 (Asia/Tokyo)

ModuleNotFoundErrorの傾向と対策:仕組みから学ぶImport

2023-apac.pycon.jp

スライド

speakerdeck.com

補足

時間の都合でお話ししなかったことをいくつか紹介します。

sys.builtin_module_names

BuiltinImporter を調べていたときに、ビルトインモジュールの一覧はないのかなと疑問に思いました。やはりあるもので、sys.builtin_module_names で取得できます。

>>> import sys
>>> sys.builtin_module_names
('_abc', '_ast', '_codecs', '_collections', '_functools', '_imp', '_io', '_locale', '_operator', '_signal', '_sre', '_stat', '_string', '_symtable', '_thread', '_tokenize', '_tracemalloc', '_typing', '_warnings', '_weakref', 'atexit', 'builtins', 'errno', 'faulthandler', 'gc', 'itertools', 'marshal', 'posix', 'pwd', 'sys', 'time')

dir 関数

組み込み関数のひとつ、dir は大変便利です。スコープやモジュールの属性を確認できます。

# 現在のスコープにあるモジュールや変数、関数などの名前一覧
>>> dir()

# ビルトインモジュールの変数、関数などの名前一覧
>>> dir(__builtins__)

# インポートしたモジュールの変数、関数などの名前一覧
>>> dir(sys)

# インポートしてないとこうなる
>>> dir(sys)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'sys' is not defined. Did you forget to import 'sys'?

DistutilsMetaFinder

Python 3.10, 3.11 には、sys.meta_path に DistutilsMetaFinder がデフォルトで設定されています(3.9 まではなかった)。

$ python
Python 3.9.18 (main, Oct 28 2023, 07:29:19) 
[Clang 14.0.3 (clang-1403.0.22.14.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.meta_path
[<class '_frozen_importlib.BuiltinImporter'>, <class '_frozen_importlib.FrozenImporter'>, <class '_frozen_importlib_external.PathFinder'>]

Python 3.10.13 (main, Oct 28 2023, 07:36:00) [Clang 14.0.3 (clang-1403.0.22.14.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.meta_path
[<_distutils_hack.DistutilsMetaFinder object at 0x104f52320>, <class '_frozen_importlib.BuiltinImporter'>, <class '_frozen_importlib.FrozenImporter'>, <class '_frozen_importlib_external.PathFinder'>]

Python 3.11.6 (main, Oct 28 2023, 07:37:02) [Clang 14.0.3 (clang-1403.0.22.14.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.meta_path
[<_distutils_hack.DistutilsMetaFinder object at 0x10280bdd0>, <class '_frozen_importlib.BuiltinImporter'>, <class '_frozen_importlib.FrozenImporter'>, <class '_frozen_importlib_external.PathFinder'>]

DistutilsMetaFinder は、PEP 632 で deprecated になった標準モジュール distutils から、互換性のある setuptools._distutils へ誘導しています。 Python 3.12 で distutils が削除されたので、DistutilsMetaFinder も設定されなくなりました。

$ python
Python 3.12.0 (main, Oct 28 2023, 07:38:14) [Clang 14.0.3 (clang-1403.0.22.14.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.meta_path
[<class '_frozen_importlib.BuiltinImporter'>, <class '_frozen_importlib.FrozenImporter'>, <class '_frozen_importlib_external.PathFinder'>]

パッケージ名が _distutils_hack なのがいいよね...

感想など

  • Python インタプリタ、たいへん奥が深いことに気づきました
  • 発表内容は、プロポーザルの段階から ChatGPT に壁打ちしてもらいながら組み立てていきました。ChatGPT の言うことを鵜呑みにはできないのでそのまま採用することはありませんが、表現方法の推敲やアイデアの幅を広げるのに役立ちました
  • スライド内の画像は Stable Diffusion や DALL-E 3 につくってもらいました