importlib.metadata – 패키지 메타데이터 액세스¶
Added in version 3.8.
버전 3.10에서 변경: importlib.metadata는 더는 잠정적이지 않습니다.
Source code: Lib/importlib/metadata/__init__.py
importlib.metadata 는 설치된 Distribution Package 의 엔트리 포인트나 최상위 이름(Import Package s, 모듈 등)과 같은 메타데이터에 액세스하는 라이브러리입니다. 파이썬의 임포트 시스템을 기반으로 구축되었으며, 이 라이브러리는 이전에 제거된 pkg_resources 패키지에 의해 노출되었던 엔트리 포인트 및 메타데이터 API를 제공합니다. importlib.resources 와 함께, pkg_resources 를 대체합니다.
importlib.metadata 는 pip 와 같은 도구를 통해 파이썬의 site-packages 디렉터리에 설치된 제삼자 배포 패키지 (distribution packages)에서 작동합니다. 특히, 발견 가능한 dist-info 또는 egg-info 디렉터리와 Core metadata specifications 에 의해 정의된 메타데이터로 작동합니다.
중요
이것들은 파이썬 코드 내부에서 임포트될 수 있는 최상위 임포트 패키지 (import package) 이름과 반드시 동등하거나 1:1로 대응하는 것은 아닙니다. 하나의 배포 패키지 는 여러 임포트 패키지 (및 단일 모듈)를 포함할 수 있으며, 네임스페이스 패키지인 경우 하나의 최상위 임포트 패키지 가 여러 배포 패키지 에 매핑될 수 있습니다. 이들 간의 매핑은 packages_distributions() 를 사용하여 얻을 수 있습니다.
기본적으로, 배포 메타데이터는 파일 시스템이나 sys.path\의 zip 아카이브에 존재할 수 있습니다. 확장 메커니즘을 통해, 메타데이터는 거의 모든 곳에 존재할 수 있습니다.
더 보기
- https://importlib-metadata.readthedocs.io/
importlib_metadata``는 ``importlib.metadata``의 역 이식본을 제공합니다. 이 문서에는 이 모듈의 클래스와 함수에 대한 `API reference <https://importlib-metadata.readthedocs.io/en/latest/api.html>`_와 기존 ``pkg_resources사용자들을 위한 `migration guide <https://importlib-metadata.readthedocs.io/en/latest/migration.html>`_가 포함되어 있습니다.
개요¶
예를 들어, pip 를 사용하여 설치한 Distribution Package 의 버전 문자열을 얻고 싶다고 가정해 보겠습니다. 먼저 가상 환경을 생성하고 그 안에 무언가를 설치하는 것으로 시작합니다:
$ 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'
또한 EntryPoint의 속성(일반적으로 ‘group’ 또는 ‘name’)으로 선택 가능한 엔트리 포인트 모음을 가져올 수도 있습니다. 예를 들어, 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를 통해 다음과 같은 기능을 제공합니다.
진입 지점¶
- importlib.metadata.entry_points(**select_params)¶
현재 환경의 진입 지점을 설명하는
EntryPoints인스턴스를 반환합니다. 주어진 키워드 매개변수는 개별 진입점 정의의 어트리뷰트와 비교하는 데select()메서드로 전달됩니다.참고:
EntryPoint.dist어트리뷰트 기준으로 진입점을 조회하려면 대신Distribution.entry_points`를 사용하십시오 (서로 다른 :class:`Distribution()인스턴스는 현재 동일한 어트리뷰트를 가지고 있더라도 동등하지 않기 때문에).
- class importlib.metadata.EntryPoints¶
설치된 진입점 컬렉션에 대한 세부 정보를 제공합니다.
식별된 모든 진입점 그룹을 보고하는
.groups어트리뷰트와 식별된 모든 진입점 이름을 보고하는.names어트리뷰트도 제공합니다.
- class importlib.metadata.EntryPoint¶
설치된 진입점에 대한 세부 정보를 제공합니다.
각
EntryPoint인스턴스에는.name,.group및.value어트리뷰트가 있고 값을 결정하는.load()메서드가 있습니다..value어트리뷰트의 구성 요소를 가져오기 위한.module,.attr및.extras어트리뷰트도 있으며,.dist는 진입 지점을 제공하는 배포 패키지에 대한 정보를 얻는데 사용됩니다.
모든 진입 지점을 조회합니다:
>>> eps = entry_points()
entry_points() 함수는 편리한 사용을 위해 names 및 groups 어트리뷰트를 가진 모든 EntryPoint 객체 컬렉션인 EntryPoints 객체를 반환합니다:
>>> sorted(eps.groups)
['console_scripts', 'distutils.commands', 'distutils.setup_keywords', 'egg_info.writers', 'setuptools.installation']
EntryPoints`는 특정 속성과 일치하는 진입점을 선택하는 :meth:!select` 메서드를 가지고 있습니다. console_scripts 그룹의 진입점을 선택합니다:
>>> scripts = eps.select(group='console_scripts')
동일하게, :func:`!entry_points`가 키워드 인수를 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 은 패키지 작성자에 의해 임의로 정의되는 값이며, 일반적으로 사용자는 특정 그룹의 모든 진입점을 해결하기를 원합니다. 진입점, 해당 정의 및 사용법에 대한 자세한 내용은 the setuptools docs 를 참조하십시오.
버전 3.12에서 변경: “selectable” 진입점은 importlib_metadata 3.6 및 Python 3.10에서 도입되었습니다. 이전 변경 사항 이전에는 entry_points``가 매개변수를 받지 않았고 항상 그룹별로 키가 지정된 진입점 딕셔너리를 반환했습니다. ``importlib_metadata 5.0 및 Python 3.12에서는 entry_points``가 항상 ``EntryPoints 객체를 반환합니다. 호환성 옵션은 :pypi:`backports.entry_points_selectable`를 참조하십시오.
버전 3.13에서 변경: EntryPoint 객체는 더 이상 튜플과 같은 인터페이스(__getitem__())를 제공하지 않습니다.
배포 메타데이터¶
- importlib.metadata.metadata(distribution_name)¶
지정된 배포 패키지에 상응하는 배포 메타데이터를
PackageMetadata인스턴스로 반환합니다.지정된 배포 패키지가 현재 Python 환경에 설치되어 있지 않으면 :exc:`PackageNotFoundError`가 발생합니다.
배포 패키지가 존재하지만 METADATA 파일이 없을 경우 :exc:`MetadataNotFound`가 발생합니다.
- class importlib.metadata.PackageMetadata¶
`PackageMetadata protocol <https://importlib-metadata.readthedocs.io/en/latest/api.html#importlib_metadata.PackageMetadata>`_의 구체적인 구현입니다.
정의된 프로토콜 메서드와 속성을 제공하는 것 외에도 인스턴스를 서브스크립팅하는 것은
get()메서드를 호출하는 것과 같습니다.
모든 배포 패키지는 metadata() 함수를 사용하여 추출할 수 있는 몇 가지 메타 데이터가 포함되어 있습니다:
>>> wheel_metadata = metadata('wheel')
반환된 데이터 구조의 키는 메타데이터 키워드의 이름을 지정하고, 값은 배포 메타데이터에서 구문 분석하지 않은 채로 반환됩니다:
>>> wheel_metadata['Requires-Python']
'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
PackageMetadata`는 또한 :PEP:`566`에 따라 모든 메타데이터를 JSON과 호환되는 형식으로 반환하는 :attr:!json` 어트리뷰트를 제공합니다:
>>> wheel_metadata.json['requires_python']
'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
사용 가능한 메타 데이터의 전체 집합은 여기에서 설명하지 않습니다. 자세한 내용은 PyPA `Core metadata specification <https://packaging.python.org/en/latest/specifications/core-metadata/#core-metadata>`_를 참조하십시오.
버전 3.15에서 변경: 이전에 우발적으로, 배포에서 METADATA 파일이 누락된 경우, 빈 PackageMetadata``가 반환되었으며 이는 비어 있는 METADATA 파일과 구별할 수 없었습니다. 이제, 누락된 METADATA 파일은 ``MetadataNotFound 예외를 발생시킵니다.
버전 3.10에서 변경: Description 은 이제 페이로드를 통해 제공될 때 메타데이터에 포함됩니다. 줄 연속 문자(line continuation characters)는 제거되었습니다.
json 어트리뷰트가 추가되었습니다.
배포 버전¶
- importlib.metadata.version(distribution_name)¶
지정된 배포 패키지에 대한 설치된 배포 패키지 `version <https://packaging.python.org/en/latest/specifications/core-metadata/#version>`_를 반환합니다.
지정된 배포 패키지가 현재 Python 환경에 설치되어 있지 않으면 :exc:`PackageNotFoundError`가 발생합니다.
version() 함수는 배포 패키지의 버전 번호를 문자열로 가져오는 가장 빠른 방법입니다:
>>> version('wheel')
'0.32.3'
배포 파일¶
- importlib.metadata.files(distribution_name)¶
이름이 지정된 배포 패키지 내부에 포함된 전체 파일 집합을
PackagePath인스턴스로 반환합니다.지정된 배포 패키지가 현재 Python 환경에 설치되어 있지 않으면 :exc:`PackageNotFoundError`가 발생합니다.
배포판은 발견되었지만, 배포 패키지와 관련된 파일 기록을 담고 있는 설치 데이터베이스 기록이 누락된 경우 :const:`None`을 반환합니다.
- class importlib.metadata.PackagePath¶
해당 파일에 대한 배포 패키지의 설치 메타 데이터에 상응하는 추가적인
dist,size및hash속성을 가진pathlib.PurePath파생 객체입니다. 또한:
- class importlib.metadata.SimplePath¶
A protocol representing a minimal subset of
pathlib.Paththat allows to check if itexists(), to traverse usingjoinpath()andparent, and to retrieve data usingread_text()andread_bytes().
files() 함수는 Distribution Package 이름을 받아 이 배포판에 의해 설치된 모든 파일을 반환합니다. 예를 들면:
>>> 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이나 다른 것으로 감쌀 수 있습니다.
배포 요구 사항¶
- importlib.metadata.requires(distribution_name)¶
이름이 지정된 배포 패키지에 대해 선언된 의존성 지정자를 반환합니다.
지정된 배포 패키지가 현재 Python 환경에 설치되어 있지 않으면 :exc:`PackageNotFoundError`가 발생합니다.
배포 패키지의 전체 요구 사항을 얻으려면, requires() 함수를 사용하십시오:
>>> requires('wheel')
["pytest (>=3.0.0) ; extra == 'test'", "pytest-cov ; extra == 'test'"]
임포트를 배포 패키지에 매핑하기¶
- importlib.metadata.packages_distributions()¶
:data:`sys.meta_path`를 통해 찾은 최상위 모듈 및 임포트 패키지 이름과, 해당 파일을 제공하는 배포 패키지 이름 간의 매핑(존재하는 경우)을 반환합니다.
네임스페이스 패키지(여러 배포 패키지에서 제공된 멤버를 가질 수 있음)의 경우, 각 최상위 임포트 이름은 단일 이름에 직접 매핑되는 대신 배포판 이름의 리스트에 매핑됩니다.
A convenience method to resolve the Distribution Package name (or names, in the case of a namespace package) that provide each importable top-level Python module or Import Package:
>>> packages_distributions()
{'importlib_metadata': ['importlib-metadata'], 'yaml': ['PyYAML'], 'jaraco': ['jaraco.classes', 'jaraco.functools'], ...}
일부 편집 가능 설치는 최상위 이름 <https://github.com/pypa/packaging-problems/issues/609>`_를 제공하지 않으며, 따라서 이 함수는 그러한 설치에서 신뢰할 수 없습니다.
Added in version 3.10.
배포¶
위에 기술된 모듈 수준 API가 가장 일반적이며 편리한 사용법이지만, 모든 정보는 Distribution 클래스에서 액세스할 수 있습니다. Distribution`은 Python `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package>`_의 메타데이터를 나타내는 추상 객체입니다. :func:`distribution 함수를 호출하여 설치된 배포 패키지의 구체적인 Distribution 서브클래스 인스턴스를 가져오세요:
>>> from importlib.metadata import distribution
>>> dist = distribution('wheel')
>>> type(dist)
<class 'importlib.metadata.PathDistribution'>
- importlib.metadata.distribution(distribution_name)¶
이름이 지정된 배포 패키지를 설명하는
Distribution인스턴스를 반환합니다.지정된 배포 패키지가 현재 Python 환경에 설치되어 있지 않으면 :exc:`PackageNotFoundError`가 발생합니다.
따라서 예를 들어 버전 번호를 얻는 다른 방법은 Distribution.version 속성을 통하는 것입니다:
>>> dist.version
'0.32.3'
:func:`entry_points`와 :func:`files`에도 동일하게 적용됩니다.
- class importlib.metadata.Distribution¶
설치된 배포 패키지에 대한 세부 정보입니다.
참고: 서로 다른
Distribution인스턴스는 동일한 설치된 배포판과 관련되어 동일한 속성을 가지고 있더라도 현재 동일하다고 비교되지 않습니다.- static at(path)¶
- classmethod from_name(name)¶
주어진 경로 또는 이름의
Distribution인스턴스를 반환합니다.
- classmethod discover(*, context=None, **kwargs)¶
모든 패키지에 대한
Distribution인스턴스의 이터러블을 반환합니다 (distribution-discovery 참조).선택적 인자 context 는
DistributionFinder.Context인스턴스로, 배포 검색을 수정하는 데 사용됩니다. 대안적으로, kwargs 는 새DistributionFinder.Context를 구성하기 위한 키워드 인자를 포함할 수 있습니다.
- metadata: PackageMetadata¶
배포판에 METADATA 파일이 없는 경우 :exc:`MetadataNotFound`를 발생시킵니다.
Distribution인스턴스에서는PackageMetadata인스턴스로 사용할 수 있는 일체의 추가 메타 데이터가 존재합니다:>>> dist.metadata['Requires-Python'] '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*' >>> dist.metadata['License'] 'MIT'
사용 가능한 메타 데이터의 전체 집합은 여기에서 설명하지 않습니다. 자세한 내용은 PyPA `Core metadata specification <https://packaging.python.org/en/latest/specifications/core-metadata/#core-metadata>`_를 참조하십시오.
- origin¶
편집 가능한 패키지의 경우,
origin속성이 PEP 610 메타 데이터(편집 불가능한 패키지의 경우,origin은None입니다)::을 제시할 수 있습니다.>>> dist.origin.url 'file:///path/to/wheel-0.32.3.editable-py3-none-any.whl'
origin객체는 `Direct URL Data Structure <https://packaging.python.org/en/latest/specifications/direct-url-data-structure/>`의 구조를 따릅니다.Added in version 3.13.
- entry_points: EntryPoints¶
이 배포 패키지에서 제공하는 진입점들입니다.
- files: list[PackagePath] | None¶
이 배포 패키지에 포함된 모든 파일. :func:`files`와 마찬가지로, 레코드가 없으면 :const:`None`을 반환합니다.
The following two abstract methods need to be implemented when implementing-custom-providers:
- locate_file(path)¶
PackagePath.locate`와 같이 지정된 경로에 대해 :class:`SimplePath`를 반환합니다. :class:`os.PathLike()또는 :class:`str`을 받습니다.
- read_text(filename)¶
distribution.locate_file(filename).read_text()의 단축 형식입니다.
배포 발견¶
기본적으로 이 패키지는 파일 시스템 및 zip 파일 Distribution Package s의 메타데이터 검색을 위한 내장 지원을 제공합니다. 이 메타데이터 파인더 검색은 sys.path 를 기본값으로 사용하지만, 다른 임포트 메커니즘이 값들을 해석하는 방식과는 약간 다릅니다. 특히:
importlib.metadata는sys.path의bytes객체를 인식하지 못합니다.importlib.metadata는 임포트를 위해 무시되는 값이라 하더라도, 부수적으로sys.path의pathlib.Path객체를 인식합니다.
- class importlib.metadata.DistributionFinder¶
설치된 배포를 검색할 수 있는
MetaPathFinder서브클래스입니다.커스텀 제공자(Custom providers)는 메타데이터를 공급하기 위해 이 인터페이스를 구현해야 합니다.
- class Context(**kwargs)¶
Context`는 커스텀 제공자에게 :func:`distributions`나 :meth:`Distribution.discover`와 같은 배포 발견 함수를 호출하는 호출자들에게서 :attr:!.name` 및 :attr:`!.path`를 넘어서는 추가 세부 정보를 요청할 수 있는 수단을 제공합니다.예를 들어, 제공자는 “public” 또는 “private”
realm내에 패키지 제품군을 노출할 수 있습니다. 배포 발견 함수를 호출하는 호출자는 특정 영역에 있는 배포만 쿼리하기를 원할 수 있으며, 커스텀 제공자에게 해당 영역의 배포만 포함하도록 신호를 보낼 수 있습니다. 이때distributions(realm="private")를 호출할 수 있습니다.각 :class:`!DistributionFinder`는 모든 매개변수를 기대해야 하며, 적절할 때 아래 정의된 표준 매개변수를 따르려고 시도해야 합니다.
자세한 내용은 커스텀 제공자 구현 섹션을 참조하십시오.
- name¶
배포 파인더가 일치해야 하는 특정 이름입니다.
None의.name은 모든 배포와 일치합니다.
- importlib.metadata.distributions(**kwargs)¶
모든 패키지에 대한
Distribution인스턴스의 반복 가능한(iterable) 객체를 반환합니다.kwargs 인수는 키워드 인수인
context,DistributionFinder.Context인스턴스, 또는 새로운DistributionFinder.Context`를 구성하기 위한 키워드 인수를 포함할 수 있습니다. :class:!DistributionFinder.Context`는 배포 검색을 수정하는 데 사용됩니다.
커스텀 제공자 구현¶
importlib.metadata 는 여러 API 표면을 다룹니다. 하나는 소비자(consumers) 를 위한 것이고 다른 하나는 제공자(providers) 를 위한 것입니다. 대부분의 사용자는 패키지가 제공하는 메타데이터를 소비하는 소비자가 됩니다. 하지만 사용자가 커스텀 임포터와 같은 다른 메커니즘과 함께 메타데이터를 노출하려는 다른 사용 사례가 있습니다. 이러한 사용 사례는 커스텀 제공자 를 필요로 합니다.
Distribution Package 메타데이터는 sys.path 검색이나 패키지 로더를 통해서는 사용 불가능하기 때문에, 배포의 메타데이터는 임포트 시스템 finders 목록을 쿼리합니다.
이 구현은 PathFinder 에 훅(hooks)을 통합하여 파일 시스템에서 발견된 배포 패키지에 대한 메타데이터를 제공합니다.
추상 클래스 importlib.abc.MetaPathFinder`는 파이썬의 import 시스템이 기대하는 finder 인터페이스를 정의합니다. ``importlib.metadata``는 :data:`sys.meta_path`의 finder에서 선택적인 ``find_distributions` callable을 찾아 이 프로토콜을 확장하고 이 확장된 인터페이스를 이 추상 메서드를 정의하는 DistributionFinder 추상 기반 클래스로 제공합니다:
@abc.abstractmethod
def find_distributions(context=DistributionFinder.Context()) -> Iterable[Distribution]:
"""지정된 ``context``의 패키지 메타데이터를 로드할 수 있는 모든 Distribution 인스턴스의 이터러블을 반환합니다.
"""
DistributionFinder.Context 객체는 검색할 경로를 나타내는 name 속성을 제공하며, 소비자(consumer)가 찾는 다른 관련 컨텍스트를 제공할 수 있습니다.
실제로, 파일 시스템 외의 위치에서 배포 패키지 메타데이터를 찾는 것을 지원하려면, Distribution`을 서브클래스화하고 추상 메서드를 구현해야 합니다. 그런 다음 사용자 지정 finder에서 ``find_distributions()` 메서드 내에 이 파생된 :class:`!Distribution`의 인스턴스를 반환합니다.
예제¶
데이터베이스에서 파이썬 모듈을 로드하는 사용자 지정 finder를 상상해 보세요:
class DatabaseImporter(importlib.abc.MetaPathFinder):
def __init__(self, db):
self.db = db
def find_spec(self, fullname, target=None) -> ModuleSpec:
return self.db.spec_from_name(fullname)
sys.meta_path.append(DatabaseImporter(connect_db(...)))
이제 그 importer는 데이터베이스에서 import 가능한 모듈을 제공하는 것으로 가정하지만, 메타데이터나 엔트리 포인트는 제공하지 않습니다. 이 사용자 지정 importer가 메타데이터를 제공하려면, :class:`DistributionFinder`도 구현해야 합니다:
from importlib.metadata import DistributionFinder
class DatabaseImporter(DistributionFinder):
...
def find_distributions(self, context=DistributionFinder.Context()):
query = dict(name=context.name) if context.name else {}
for dist_record in self.db.query_distributions(query):
yield DatabaseDistribution(dist_record)
이런 방식으로, query_distributions 는 쿼리에 맞는 데이터베이스가 제공하는 각 배포에 대한 레코드를 반환합니다. 예를 들어, requests-1.0 이 데이터베이스에 있다면, find_distributions 는 Context(name='requests') 또는 Context(name=None) 에 대한 DatabaseDistribution 을 생성할 것입니다.
단순화를 위해, 이 예제에서는 context.path``를 무시합니다. ``path 속성은 sys.path``로 기본 설정되며 검색 시 고려할 import 경로의 집합입니다. ``DatabaseImporter``는 검색 경로에 대한 고려 없이 기능할 수도 있습니다. importer가 파티셔닝을 수행하지 않는다고 가정하면, "path"는 무관합니다. ``path``의 목적을 설명하려면, ``sys.path/PYTHONPATH``에 따라 동작이 달라지는 더 복잡한 ``DatabaseImporter``를 예시로 보여줘야 합니다. 그 경우, ``find_distributions``는 ``context.path``를 존중하여 ``Distributions가 해당 경로와 관련된 것만 생성해야 합니다.
그러면 DatabaseDistribution 은 다음과 같은 형태일 것입니다:
class DatabaseDistribution(importlib.metadata.Distribution):
def __init__(self, record):
self.record = record
def read_text(self, filename):
"""
Read a file like "METADATA" for the current distribution.
"""
if filename == "METADATA":
return f"""Name: {self.record.name}
Version: {self.record.version}
"""
if filename == "entry_points.txt":
return "\n".join(
f"""[{ep.group}]\n{ep.name}={ep.value}"""
for ep in self.record.entry_points)
def locate_file(self, path):
raise RuntimeError("This distribution has no file system")
이 기본 구현은 record 가 적절한 .name, .version, 및 .entry_points 속성을 제공한다는 가정 하에, DatabaseImporter 가 제공하는 패키지의 메타데이터와 엔트리 포인트를 제공해야 합니다.
DatabaseDistribution 은 또한 RECORD 와 같은 다른 메타데이터 파일도 제공할 수 있습니다 (Distribution.files 에 필요함) 또는 Distribution.files 의 구현을 덮어쓸 수 있습니다. 더 많은 영감을 얻으려면 소스를 참고하십시오.