PyCon APAC 2023 Day1 で ModuleNotFoundError に関する発表をしました
参加記はまた別で書きます。
会場では 30 名くらい?の方々が聴きにきてくれました。ありがとうございます。
発表したこと
タイトル
2023/10/27 16:20 ~ 16:35 (Asia/Tokyo)
ModuleNotFoundErrorの傾向と対策:仕組みから学ぶImport
スライド
補足
時間の都合でお話ししなかったことをいくつか紹介します。
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
なのがいいよね...