importlib.metadata
-- パッケージメタデータへのアクセス¶
Added in version 3.8.
バージョン 3.10 で変更: importlib.metadata
は暫定的なものではなくなりました。
ソースコード: Lib/importlib/metadata/__init__.py
importlib.metadata
はインストールされた 配布パッケージ のエントリポイントやトップレベル名 (あれば、 パッケージ やモジュール) のようなメタデータへのアクセスを提供するライブラリです。Pythonのインポートシステムをベースに構築されており、このライブラリは pkg_resources
の entry point API と metadata API にある同様の機能を置き換えることを目的としています。importlib.resources
と共に、このパッケージは古くて効率の悪い pkg_resources
パッケージを使う必要性を無くすことができます。
importlib.metadata
は、Pythonの site-packages
ディレクトリに pip などのツールでインストールしたサードパーティの 配布パッケージ に対して動作します。具体的には、 dist-info
や egg-info
ディレクトリを持つ配布物や、 コアとなるメタデータの仕様 で定義されたメタデータを検出できるようにします。
重要
These are not necessarily equivalent to or correspond 1:1 with the top-level import package names that can be imported inside Python code. One distribution package can contain multiple import packages (and single modules), and one top-level import package may map to multiple distribution packages if it is a namespace package. You can use package_distributions() to get a mapping between them.
デフォルトでは、配布物のメタデータはファイルシステム上、または sys.path
のzipアーカイブに保存されます。拡張機構により、メタデータはほとんどどこにでも置くことができます。
参考
- https://importlib-metadata.readthedocs.io/
importlib_metadata
のドキュメントはimportlib.metadata
のバックポートです。これには、このモジュールのクラスと関数の APIリファレンス と、pkg_resources
の既存のユーザーのための 移行ガイド があります。
概要¶
例えば、pip
を使ってインストールした 配布パッケージ のバージョン文字列を取得したいとします。 まず、仮想環境を作成し、そこに何かをインストールすることから始めましょう:
$ python -m venv example
$ source example/bin/activate
(example) $ python -m pip install wheel
以下のように実行することで、wheel
のバージョン文字列を取得することができます:
(example) $ python
>>> from importlib.metadata import version
>>> version('wheel')
'0.32.3'
また、 console_scripts
や distutils.commands
などのエントリポイントのプロパティ(通常は 'group' や 'name' )で選択可能なエントリポイントの集合を取得することができます。 各グループは エントリポイント オブジェクトの集合を含んでいます。
ディストリビューションのメタデータ を取得することができます。:
>>> list(metadata('wheel'))
['Metadata-Version', 'Name', 'Version', 'Summary', 'Home-page', 'Author', 'Author-email', 'Maintainer', 'Maintainer-email', 'License', 'Project-URL', 'Project-URL', 'Project-URL', 'Keywords', 'Platform', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Requires-Python', 'Provides-Extra', 'Requires-Dist', 'Requires-Dist']
また、 配布物のバージョン番号 を取得し、 構成ファイル をリストアップし、配布物の 配布物の要件 のリストを取得することができます。
機能 API¶
本パッケージは、公開APIを通じて以下の機能を提供します。
エントリポイント¶
entry_points()
関数は、エントリポイントの集合を返します。各 EntryPoint
は .name
, .group
, .value
属性と値を解決する .load()
メソッドを持っています。 また、 .value
属性の構成要素を取得するための .module
, .attr
, .extras
属性が存在します。
すべてのエントリポイントに問い合わせる:
>>> eps = entry_points()
entry_points()
関数は、すべての EntryPoint
オブジェクトを集めた EntryPoints
オブジェクトを、便宜上 names
と groups
属性を付けて返します。
>>> sorted(eps.groups)
['console_scripts', 'distutils.commands', 'distutils.setup_keywords', 'egg_info.writers', 'setuptools.installation']
EntryPoints
には、特定のプロパティに一致するエントリポイントを選択するための select
メソッドがあります。console_scripts
グループ内のエントリポイントを選択する:
>>> scripts = eps.select(group='console_scripts')
Equivalently, since entry_points
passes keyword arguments
through to select:
>>> scripts = entry_points(group='console_scripts')
"wheel" という名前の特定のスクリプトを選択します。(wheelプロジェクトにあります):
>>> 'wheel' in scripts.names
True
>>> wheel = scripts['wheel']
同様に、選択時にそのエントリポイントを問い合わせます:
>>> (wheel,) = entry_points(group='console_scripts', name='wheel')
>>> (wheel,) = entry_points().select(group='console_scripts', name='wheel')
解決したエントリポイントを検証する:
>>> wheel
EntryPoint(name='wheel', value='wheel.cli:main', group='console_scripts')
>>> wheel.module
'wheel.cli'
>>> wheel.attr
'main'
>>> wheel.extras
[]
>>> main = wheel.load()
>>> main
<function main at 0x103528488>
group
と name
はパッケージの作者によって定義された任意の値で、通常クライアントは特定のグループのエントリポイントを解決したいと思うでしょう。エントリポイント、その他の定義、使用方法についての詳細は setuptoolsのドキュメント を参照してください。
Compatibility Note
The "selectable" entry points were introduced in importlib_metadata
3.6 and Python 3.10. Prior to those changes, entry_points
accepted
no parameters and always returned a dictionary of entry points, keyed
by group. With importlib_metadata
5.0 and Python 3.12,
entry_points
always returns an EntryPoints
object. See
backports.entry_points_selectable
for compatibility options.
配布物メタデータ¶
すべての 配布パッケージ にはメタデータが含まれており、 metadata()
関数を使って取得することができます:
>>> wheel_metadata = metadata('wheel')
返されたデータ構造である PackageMetadata
のキーはメタデータのキーワードを表し、値は配布パッケージのメタデータから解析されずに返されます:
>>> wheel_metadata['Requires-Python']
'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
PackageMetadata
には json
属性があり、 PEP 566 に従ってすべてのメタデータをJSON互換の形式で返します:
>>> wheel_metadata.json['requires_python']
'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
注釈
metadata()
が返すオブジェクトの実際の型は実装の詳細であり、 PackageMetadataプロトコル が示すインターフェースを通じてのみアクセスすることができます。
バージョン 3.10 で変更: ペイロードを通して提示されるとき、 Description
がメタデータに含まれるようになりました。行の継続文字は削除されました。
json
属性が追加されました。
配布物バージョン¶
version()
関数は 配布パッケージ のバージョン番号を文字列で取得するもっとも簡単な方法です。:
>>> version('wheel')
'0.32.3'
配布物ファイル¶
また、配布パッケージに含まれるファイルのフルセットを取得することもできます。files()
関数は 配布パッケージ 名を受け取り、この配布パッケージにインストールされているすべてのファイルを返します。返される各ファイルオブジェクトは PackagePath
で、 pathlib.PurePath
から派生したオブジェクトに、メタデータで示された dist
, size
, hash
プロパティを追加しています。 例えば:
>>> util = [p for p in files('wheel') if 'util.py' in str(p)][0]
>>> util
PackagePath('wheel/util.py')
>>> util.size
859
>>> util.dist
<importlib.metadata._hooks.PathDistribution object at 0x101e0cef0>
>>> util.hash
<FileHash mode: sha256 value: bYkw5oMccfazVCoYQwKkkemoVyMAFoR34mmKBx8R1NI>
ファイルを取得したら、その内容を読むこともできます:
>>> print(util.read_text())
import base64
import sys
...
def as_bytes(s):
if isinstance(s, text_type):
return s.encode('utf-8')
return s
また、 locate
メソッドを使用すると、ファイルへの絶対パスを取得することができます:
>>> util.locate()
PosixPath('/home/gustav/example/lib/site-packages/wheel/util.py')
In the case where the metadata file listing files
(RECORD or SOURCES.txt) is missing, files()
will
return None
. The caller may wish to wrap calls to
files()
in always_iterable
or otherwise guard against this condition if the target
distribution is not known to have the metadata present.
配布物の要件¶
配布パッケージ に必要なすべての要件を取得するには、 requires()
関数を使用します:
>>> requires('wheel')
["pytest (>=3.0.0) ; extra == 'test'", "pytest-cov ; extra == 'test'"]
Mapping import to distribution packages¶
インポート可能なトップレベルのPythonモジュールまたは パッケージ を提供する 配布パッケージ 名(名前空間パッケージの場合はその名前)を解決する便利なメソッドです:
>>> packages_distributions()
{'importlib_metadata': ['importlib-metadata'], 'yaml': ['PyYAML'], 'jaraco': ['jaraco.classes', 'jaraco.functools'], ...}
Some editable installs, do not supply top-level names, and thus this function is not reliable with such installs.
Added in version 3.10.
Distributions¶
上記のAPIは最も一般的で便利な使い方ですが、 Distribution
クラスからすべての情報を得ることができます。 Distribution
はPython 配布パッケージ のメタデータを表す抽象オブジェクトです。 Distribution
のインスタンスを取得することができます。
>>> from importlib.metadata import distribution
>>> dist = distribution('wheel')
したがって、バージョン情報を取得する別の方法として、 Distribution
インスタンスを使用します:
>>> dist.version
'0.32.3'
Distribution
インスタンスには、あらゆる種類の追加メタデータが用意されています:
>>> dist.metadata['Requires-Python']
'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
>>> dist.metadata['License']
'MIT'
利用可能なメタデータのフルセットは、ここでは説明しません。詳細は コアとなるメタデータの仕様 を参照してください。
Distribution Discovery¶
デフォルトでは、このパッケージは組み込みで、ファイルシステムおよび zip ファイル 配布パッケージ のメタデータを発見するためのサポートを提供します。このメタデータ検索のデフォルトは sys.path
ですが、その値をどのように解釈するかは、他のインポート機構が行う方法とは若干異なります。具体的には:
importlib.metadata
はsys.path
のbytes
オブジェクトを受け入れません。importlib.metadata
は、インポート時には無視されますが、sys.path
上のpathlib.Path
オブジェクトを優先的に使用します。
検索アルゴリズムの拡張¶
Because Distribution Package metadata
is not available through sys.path
searches, or
package loaders directly,
the metadata for a distribution is found through import
system finders. To find a distribution package's metadata,
importlib.metadata
queries the list of meta path finders on
sys.meta_path
.
By default importlib.metadata
installs a finder for distribution packages
found on the file system.
This finder doesn't actually find any distributions,
but it can find their metadata.
抽象クラス importlib.abc.MetaPathFinder
はPythonの importシステムによってファインダーに期待されるインターフェイスを定義しています。 importlib.metadata
はこのプロトコルを拡張し、 sys.meta_path
からファインダーにオプションの find_distributions
を呼び出すことができるようにし、この拡張インターフェースを DistributionFinder
抽象基底クラスとして提示し、この抽象メソッドを定義しています:
@abc.abstractmethod
def find_distributions(context=DistributionFinder.Context()):
"""Return an iterable of all Distribution instances capable of
loading the metadata for packages for the indicated ``context``.
"""
DistributionFinder.Context
オブジェクトは、検索するパスと一致する名前を示す .path
と .name
のプロパティを提供し、その他の関連するコンテキストを提供することもできます。
つまり、ファイルシステム以外の場所にある配布パッケージのメタデータを見つけるには、 Distribution
をサブクラス化して抽象メソッドを実装します。そして、カスタムファインダーから find_distributions()
メソッドで、派生した Distribution
のインスタンスを返します。