importlib.metadataの使用—Pythonドキュメント

提供:Dev Guides
< PythonPython/docs/3.10/library/importlib.metadata
移動先:案内検索

importlib.metadataを使用する

バージョン3.8の新機能。


バージョン3.10で変更: importlib.metadataは暫定的ではなくなりました。


ソースコード: :source: `Lib / importlib / metadata.py`

importlib.metadataは、インストールされたパッケージメタデータへのアクセスを提供するライブラリです。 Pythonのインポートシステムに一部組み込まれているこのライブラリは、pkg_resourcesエントリポイントAPI およびメタデータAPI の同様の機能を置き換えることを目的としています。 Python3.7以降の importlib.resources (古いバージョンのPythonでは importlib_resources としてバックポートされます)とともに、これにより、古くて効率の悪いpkg_resourcesを使用する必要がなくなります。 ] パッケージ。

「インストール済みパッケージ」とは、通常、 pip などのツールを介してPythonのsite-packagesディレクトリにインストールされるサードパーティパッケージを意味します。 具体的には、検出可能なdist-infoまたはegg-infoディレクトリと、 PEP 566 またはその古い仕様で定義されたメタデータを持つパッケージを意味します。 デフォルトでは、パッケージメタデータはファイルシステムまたは sys.path のzipアーカイブに存在できます。 拡張メカニズムにより、メタデータはほぼどこにでも存在できます。

概要

pipを使用してインストールしたパッケージのバージョン文字列を取得したいとします。 まず、仮想環境を作成し、それに何かをインストールします。

$ python3 -m venv example
$ source example/bin/activate
(example) $ pip install wheel

次のコマンドを実行すると、wheelのバージョン文字列を取得できます。

(example) $ python
>>> from importlib.metadata import version  
>>> version('wheel')  
'0.32.3'

console_scriptsdistutils.commandsなど、グループごとにキー設定されたエントリポイントのセットを取得することもできます。 各グループには、一連の EntryPoint オブジェクトが含まれています。

ディストリビューションメタデータを取得できます。

>>> 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インスタンスで表されます。 各EntryPointには、.name.group、および.value属性と、値を解決するための.load()メソッドがあります。 .value属性のコンポーネントを取得するための.module.attr、および.extras属性もあります。

すべてのエントリポイントをクエリします。

>>> eps = entry_points()

entry_points()関数は、EntryPointsオブジェクトを返します。これは、便宜上、namesおよびgroups属性を持つすべてのEntryPointオブジェクトのシーケンスです。

>>> 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')

同様に、entry_pointsはキーワード引数を渡して、以下を選択します。

>>> 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 docs をお読みください。

互換性に関する注意

「選択可能な」エントリポイントは、importlib_metadata 3.6およびPython3.10で導入されました。 これらの変更の前は、entry_pointsはパラメーターを受け入れず、常にグループごとにキー設定されたエントリポイントのディクショナリを返していました。 互換性のために、entry_pointsにパラメーターが渡されない場合、SelectableGroupsオブジェクトが返され、そのdictインターフェースが実装されます。 将来的には、パラメータなしでentry_pointsを呼び出すと、EntryPointsオブジェクトが返されます。 ユーザーは、選択インターフェイスを使用して、グループごとにエントリポイントを取得する必要があります。


配布メタデータ

すべてのディストリビューションには、metadata()関数を使用して抽出できるメタデータが含まれています。

>>> wheel_metadata = metadata('wheel')

返されるデータ構造のキーPackageMetadataは、メタデータキーワードに名前を付け、値は分散メタデータから解析されずに返されます。

>>> wheel_metadata['Requires-Python']  
'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'

PackageMetadataは、 PEP 566 に従ってすべてのメタデータをJSON互換形式で返すjson属性も提供します。

>>> wheel_metadata.json['requires_python']
'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'

バージョン3.10で変更: Descriptionは、ペイロードを介して提示されるときにメタデータに含まれるようになりました。 行継続文字が削除されました。


バージョン3.10の新機能: json属性が追加されました。


配布バージョン

version()関数は、ディストリビューションのバージョン番号を文字列として取得する最も簡単な方法です。

>>> version('wheel')  
'0.32.3'

配布ファイル

ディストリビューションに含まれるファイルのフルセットを取得することもできます。 files()関数は、ディストリビューションパッケージ名を受け取り、このディストリビューションによってインストールされたすべてのファイルを返します。 返される各ファイルオブジェクトは、PackagePathpathlib.PurePath 派生オブジェクトであり、追加のdistsize、および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')

メタデータファイル一覧ファイル(RECORDまたはSOURCES.txt)がない場合、files()Noneを返します。 呼び出し元は、files()への呼び出しを always_iterable でラップするか、ターゲットディストリビューションにメタデータが存在することがわかっていない場合にこの状態を防ぐことができます。


配布要件

ディストリビューションの要件の完全なセットを取得するには、requires()関数を使用します。

>>> requires('wheel')  
["pytest (>=3.0.0) ; extra == 'test'", "pytest-cov ; extra == 'test'"]

パッケージの配布

トップレベルのPythonパッケージまたはモジュールの1つまたは複数のディストリビューション(名前空間パッケージの場合)を解決するための便利な方法:

>>> packages_distributions()
{'importlib_metadata': ['importlib-metadata'], 'yaml': ['PyYAML'], 'jaraco': ['jaraco.classes', 'jaraco.functools'], ...}

バージョン3.10の新機能。


ディストリビューション

上記の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'

利用可能なメタデータの完全なセットについては、ここでは説明しません。 詳細については、 PEP 566 を参照してください。


検索アルゴリズムの拡張

パッケージメタデータは sys.path 検索、またはパッケージローダーから直接利用できないため、パッケージのメタデータはインポートシステムファインダーから検出されます。 配布パッケージのメタデータを検索するために、importlib.metadatasys.meta_path 上のメタパスファインダーのリストを照会します。

PythonのデフォルトのPathFinderには、一般的なファイルシステムベースのパスからロードされたディストリビューションを検索するためにimportlib.metadata.MetadataPathFinderを呼び出すフックが含まれています。

抽象クラス importlib.abc.MetaPathFinder は、Pythonのインポートシステムがファインダーに期待するインターフェースを定義します。 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をサブクラス化し、抽象メソッドを実装することです。 次に、カスタムファインダーから、この派生したDistributionのインスタンスをfind_distributions()メソッドで返します。

脚注