importlib.metadata
사용하기¶
버전 3.8에 추가.
버전 3.10에서 변경: importlib.metadata
is no longer provisional.
Source code: Lib/importlib/metadata/__init__.py
importlib.metadata
는 설치된 패키지 메타 데이터에 대한 액세스를 제공하는 라이브러리입니다. 파이썬의 임포트 시스템에 내장된 이 라이브러리는 pkg_resources
의 진입 지점 API와 메타데이터 API에서 유사한 기능을 대체하려고 합니다. 파이썬 3.7 이상의 importlib.resources
(이전 버전의 파이썬을 위해 importlib_resources로 역 이식되었습니다)와 함께, 오래되고 덜 효율적인 pkg_resources
패키지를 사용할 필요를 제거합니다.
“설치된 패키지”는 일반적으로 pip 와 같은 도구를 통해 파이썬의 site-packages
디렉터리에 설치된 제삼자 패키지를 의미합니다. 특히, 발견 가능한 dist-info
나 egg-info
디렉터리와 PEP 566 또는 이전 명세로 정의된 메타 데이터가 있는 패키지를 의미합니다. 기본적으로, 패키지 메타 데이터는 파일 시스템이나 sys.path
의 zip 저장소에서 살 수 있습니다. 확장 메커니즘을 통해, 메타 데이터는 거의 모든 곳에서 살아갈 수 있습니다.
개요¶
pip
를 사용하여 설치한 패키지의 버전 문자열을 얻고 싶다고 가정해 봅시다. 우선 가상 환경을 만들고 그 안에 뭔가 설치합니다:
$ python -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_scripts
, distutils.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를 통해 다음과 같은 기능을 제공합니다.
진입 지점¶
The entry_points()
function returns a collection of entry points.
Entry points are represented by EntryPoint
instances;
each EntryPoint
has a .name
, .group
, and .value
attributes and
a .load()
method to resolve the value. There are also .module
,
.attr
, and .extras
attributes for getting the components of the
.value
attribute.
Query all entry points:
>>> eps = entry_points()
The entry_points()
function returns an EntryPoints
object,
a sequence of all EntryPoint
objects with names
and groups
attributes for convenience:
>>> sorted(eps.groups)
['console_scripts', 'distutils.commands', 'distutils.setup_keywords', 'egg_info.writers', 'setuptools.installation']
EntryPoints
has a select
method to select entry points
matching specific properties. Select entry points in the
console_scripts
group:
>>> scripts = eps.select(group='console_scripts')
Equivalently, since entry_points
passes keyword arguments
through to select:
>>> scripts = entry_points(group='console_scripts')
Pick out a specific script named “wheel” (found in the wheel project):
>>> 'wheel' in scripts.names
True
>>> wheel = scripts['wheel']
Equivalently, query for that entry point during selection:
>>> (wheel,) = entry_points(group='console_scripts', name='wheel')
>>> (wheel,) = entry_points().select(group='console_scripts', name='wheel')
Inspect the resolved entry point:
>>> 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>
The group
and name
are arbitrary values defined by the package author
and usually a client will wish to resolve all entry points for a particular
group. Read the setuptools docs
for more information on entry points, their definition, and usage.
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. For compatibility, if no parameters are passed to entry_points,
a SelectableGroups
object is returned, implementing that dict
interface. In the future, calling entry_points
with no parameters
will return an EntryPoints
object. Users should rely on the selection
interface to retrieve entry points by group.
배포 메타데이터¶
모든 배포는 metadata()
함수를 사용하여 추출할 수 있는 몇 가지 메타 데이터가 포함되어 있습니다:
>>> wheel_metadata = metadata('wheel')
The keys of the returned data structure, a PackageMetadata
,
name the metadata keywords, and
the values are returned unparsed from the distribution metadata:
>>> wheel_metadata['Requires-Python']
'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
PackageMetadata
also presents a json
attribute that returns
all the metadata in a JSON-compatible form per PEP 566:
>>> wheel_metadata.json['requires_python']
'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
버전 3.10에서 변경: The Description
is now included in the metadata when presented
through the payload. Line continuation characters have been removed.
버전 3.10에 추가: The json
attribute was added.
배포 버전¶
version()
함수는 배포의 버전 번호를 문자열로 가져오는 가장 빠른 방법입니다:
>>> version('wheel')
'0.32.3'
배포 파일¶
You can also get the full set of files contained within a distribution. The
files()
function takes a distribution package name and returns all of the
files installed by this distribution. Each file object returned is a
PackagePath
, a pathlib.PurePath
derived object with additional dist
,
size
, and hash
properties as indicated by the metadata. For example:
>>> 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
You can also use the locate
method to get a the absolute path to the
file:
>>> 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'"]
Package distributions¶
A convenience method to resolve the distribution or distributions (in the case of a namespace package) for top-level Python packages or modules:
>>> packages_distributions()
{'importlib_metadata': ['importlib-metadata'], 'yaml': ['PyYAML'], 'jaraco': ['jaraco.classes', 'jaraco.functools'], ...}
버전 3.10에 추가.
배포¶
위의 API가 가장 일반적이며 편리한 사용법이지만, Distribution
클래스에서 모든 정보를 얻을 수 있습니다. Distribution
은 파이썬 패키지의 메타 데이터를 나타내는 추상 객체입니다. 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.metadata
는 sys.meta_path
의 메타 경로 파인더의 리스트를 조회합니다.
파이썬의 기본 PathFinder
에는 일반적인 파일 시스템 기반 경로에서 로드된 배포를 찾기 위해 importlib.metadata.MetadataPathFinder
를 호출하는 훅이 포함되어 있습니다.
추상 클래스 importlib.abc.MetaPathFinder
는 파이썬의 임포트 시스템에 의해 파인더가 기대하는 인터페이스를 정의합니다. 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
의 인스턴스를 반환하십시오.