importlib.metadata
– Acessando metadados do pacote¶
Adicionado na versão 3.8.
Alterado na versão 3.10: importlib.metadata
não é mais provisório.
Código-fonte: Lib/importlib/metadata/__init__.py
importlib.metadata
é uma biblioteca que fornece acesso aos metadados de um Pacote de Distribuição instalado, como seus pontos de entrada ou seus nomes de nível superior (Pacotes de Importação, módulos, se houver). Construída em parte no sistema de importação do Python, esta biblioteca pretende substituir funcionalidades semelhantes na API de ponto de entrada e API de metadados de pkg_resources
. Junto com importlib.resources
, este pacote pode eliminar a necessidade de usar o pacote pkg_resources
mais antigo e menos eficiente.
importlib.metadata
opera em pacotes de distribuição de terceiros instalados no diretório site-packages
do Python através de ferramentas como pip. Especificamente, ele funciona com distribuições com diretórios dist-info
ou egg-info
detectáveis, e metadados definidos pelas Especificações de metadados principais.
Importante
Eles não são necessariamente equivalentes ou correspondem 1:1 aos nomes de pacotes de importação de nível superior que podem ser importados dentro do código Python. Um pacote de distribuição pode conter vários pacotes de importação (e módulos únicos), e um pacote de importação de nível superior pode mapear para vários pacotes de distribuição se for um pacote de espaço de nomes. Você pode usar package_distributions() para obter um mapeamento entre eles.
Por padrão, os metadados de distribuição podem residir no sistema de arquivos ou em arquivos zip em sys.path
. Através de um mecanismo de extensão, os metadados podem residir em praticamente qualquer lugar.
Ver também
- https://importlib-metadata.readthedocs.io/
A documentação para
importlib_metadata
, que fornece um backport deimportlib.metadata
. Isso inclui uma referência de API para as classes e funções deste módulo, bem como um guia de migração para usuários existentes depkg_resources
.
Visão Geral¶
Digamos que você queira obter a string da versão de um Pacote de Distribuição que você instalou usando pip
. Começamos criando um ambiente virtual e instalando algo nele:
$ python -m venv example
$ source example/bin/activate
(example) $ python -m pip install wheel
Você pode obter a string de versão para wheel
executando o seguinte:
(example) $ python
>>> from importlib.metadata import version
>>> version('wheel')
'0.32.3'
Você também pode obter uma coleção de pontos de entrada selecionáveis pelas propriedades do EntryPoint (normalmente ‘group’ ou ‘name’), como console_scripts
, distutils.commands
e outros. Cada grupo contém uma coleção de objetos EntryPoint.
Você pode obter os metadados para uma distribuição:
>>> 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']
Você também pode obter uma número da versão da distribuição, listar seus arquivos constituintes e obter uma lista dos Requisitos de distribuição da distribuição.
- exception importlib.metadata.PackageNotFoundError¶
Subclass of
ModuleNotFoundError
raised by several functions in this module when queried for a distribution package which is not installed in the current Python environment.
API funcional¶
Este pacote fornece a seguinte funcionalidade por meio de sua API pública.
Pontos de entrada¶
- importlib.metadata.entry_points(**select_params)¶
Returns a
EntryPoints
instance describing entry points for the current environment. Any given keyword parameters are passed to theselect()
method for comparison to the attributes of the individual entry point definitions.Note: it is not currently possible to query for entry points based on their
EntryPoint.dist
attribute (as differentDistribution
instances do not currently compare equal, even if they have the same attributes)
- class importlib.metadata.EntryPoints¶
Details of a collection of installed entry points.
Also provides a
.groups
attribute that reports all identifed entry point groups, and a.names
attribute that reports all identified entry point names.
- class importlib.metadata.EntryPoint¶
Details of an installed entry point.
Each
EntryPoint
instance has.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, and.dist
for obtaining information regarding the distribution package that provides the entry point.
Consultar todos os pontos de entrada:
>>> eps = entry_points()
The entry_points()
function returns a EntryPoints
object,
a collection 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')
Escolha um script específico chamado “wheel” (encontrado no projeto wheel):
>>> 'wheel' in scripts.names
True
>>> wheel = scripts['wheel']
De forma equivalente, consulte esse ponto de entrada durante a seleção:
>>> (wheel,) = entry_points(group='console_scripts', name='wheel')
>>> (wheel,) = entry_points().select(group='console_scripts', name='wheel')
Inspecione o ponto de entrada resolvido:
>>> 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>
O group
e name
são valores arbitrários definidos pelo autor do pacote e normalmente um cliente desejará resolver todos os pontos de entrada para um grupo específico. Leia a documentação do setuptools para obter mais informações sobre pontos de entrada, sua definição e uso.
Notas de compatibilidade
Os pontos de entrada “selecionáveis” foram introduzidos em importlib_metadata
3.6 e Python 3.10. Antes dessas mudanças, entry_points
não aceitava parâmetros e sempre retornava um dicionário de pontos de entrada, chaveado por grupo. Com importlib_metadata
5.0 e Python 3.12, entry_points
sempre retorna um objeto EntryPoints
. Veja backports.entry_points_selectable para opções de compatibilidade.
Metadados de distribuição¶
- importlib.metadata.metadata(distribution_name)¶
Return the distribution metadata corresponding to the named distribution package as a
PackageMetadata
instance.Raises
PackageNotFoundError
if the named distribution package is not installed in the current Python environment.
- class importlib.metadata.PackageMetadata¶
- A concrete implementation of the
-
In addition to providing the defined protocol methods and attributes, subscripting the instance is equivalent to calling the
get()
method.
Every Distribution Package
includes some metadata, which you can extract using the metadata()
function:
>>> wheel_metadata = metadata('wheel')
The keys of the returned data structure 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.*'
The full set of available metadata is not described here. See the PyPA Core metadata specification for additional details.
Alterado na versão 3.10: A Description
agora é incluída nos metadados quando apresentada através do payload. Os caracteres de continuação de linha foram removidos.
O atributo json
foi adicionado.
Versões de distribuição¶
- importlib.metadata.version(distribution_name)¶
Return the installed distribution package version for the named distribution package.
Raises
PackageNotFoundError
if the named distribution package is not installed in the current Python environment.
The version()
function is the quickest way to get a
Distribution Package’s version
number, as a string:
>>> version('wheel')
'0.32.3'
Arquivos de distribuição¶
- importlib.metadata.files(distribution_name)¶
Return the full set of files contained within the named distribution package.
Raises
PackageNotFoundError
if the named distribution package is not installed in the current Python environment.Returns
None
if the distribution is found but the installation database records reporting the files associated with the distribuion package are missing.
- class importlib.metadata.PackagePath¶
A
pathlib.PurePath
derived object with additionaldist
,size
, andhash
properties corresponding to the distribution package’s installation metadata for that file.
The files()
function takes a
Distribution Package
name and returns all of the files installed by this distribution. Each file is reported
as a PackagePath
instance. 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>
Uma vez que tenha o arquivo, você também pode ler seu conteúdo:
>>> 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 the absolute
path to the file:
>>> 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.
Requisitos de distribuição¶
- importlib.metadata.requires(distribution_name)¶
Return the declared dependency specifiers for the named distribution package.
Raises
PackageNotFoundError
if the named distribution package is not installed in the current Python environment.
To get the full set of requirements for a Distribution Package,
use the requires()
function:
>>> requires('wheel')
["pytest (>=3.0.0) ; extra == 'test'", "pytest-cov ; extra == 'test'"]
Mapeando importação pra pacotes de distribuição¶
- importlib.metadata.packages_distributions()¶
Return a mapping from the top level module and import package names found via
sys.meta_path
to the names of the distribution packages (if any) that provide the corresponding files.To allow for namespace packages (which may have members provided by multiple distribution packages), each top level import name maps to a list of distribution names rather than mapping directly to a single name.
Um método conveniente para resolver o nome do Pacote de Distribuição (ou nomes, no caso de um pacote de espaço de nomes) que fornece cada módulo Python de nível superior importável ou Pacote de Importação:
>>> packages_distributions()
{'importlib_metadata': ['importlib-metadata'], 'yaml': ['PyYAML'], 'jaraco': ['jaraco.classes', 'jaraco.functools'], ...}
Algumas instalações editáveis não fornecem nomes de nível superior e, portanto, esta função não é confiável com tais instalações.
Adicionado na versão 3.10.
Distribuições¶
- importlib.metadata.distribution(distribution_name)¶
Return a
Distribution
instance describing the named distribution package.Raises
PackageNotFoundError
if the named distribution package is not installed in the current Python environment.
- class importlib.metadata.Distribution¶
Details of an installed distribution package.
Note: different
Distribution
instances do not currently compare equal, even if they relate to the same installed distribution and accordingly have the same attributes.
While the module level API described above is the most common and convenient usage,
you can get all of that information from the Distribution
class.
Distribution
is an abstract object that represents the metadata for
a Python Distribution Package.
You can get the concreate Distribution
subclass instance for an installed
distribution package by calling the distribution()
function:
>>> from importlib.metadata import distribution
>>> dist = distribution('wheel')
>>> type(dist)
<class 'importlib.metadata.PathDistribution'>
Thus, an alternative way to get the version number is through the
Distribution
instance:
>>> dist.version
'0.32.3'
There are all kinds of additional metadata available on Distribution
instances:
>>> dist.metadata['Requires-Python']
'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
>>> dist.metadata['License']
'MIT'
The full set of available metadata is not described here. See the PyPA Core metadata specification for additional details.
Descoberta de distribuição¶
Por padrão, este pacote fornece suporte embutido para descoberta de metadados para sistema de arquivos e arquivo zip Pacotes de Distribuição. Esta pesquisa do localizador de metadados tem como padrão sys.path
, mas varia um pouco na maneira como ela interpreta esses valores em relação a outras mecanismo de importação. Em particular:
importlib.metadata
não honra objetosbytes
emsys.path
.importlib.metadata
irá incidentalmente honrar objetospathlib.Path
emsys.path
mesmo que tais valores sejam ignorados para importações.
Estendendo o algoritmo de pesquisa¶
Como os metadados de Pacote de Distribuição não estão disponíveis por meio de pesquisas a sys.path
ou carregadores de pacotes diretamente, os metadados de uma distribuição são encontrados através de localizadores do sistema de importação. Para encontrar os metadados de um pacote de distribuição, importlib.metadata
consulta a lista de localizadores de metacaminho em sys.meta_path
.
Por padrão importlib.metadata
instala um localizador para pacotes de distribuição encontrados no sistema de arquivos. Na verdade, esse localizador não encontra nenhuma distribuição, mas pode encontrar seus metadados.
A classe abstrata importlib.abc.MetaPathFinder
define a interface esperada dos localizadores pelo sistema de importação do Python. importlib.metadata
estende este protocolo procurando por um chamável find_distributions
opcional nos localizadores de sys.meta_path
e apresenta esta interface estendida como a classe base abstrata DistributionFinder
, que define este método abstrato:
@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``.
"""
O objeto DistributionFinder.Context
fornece propriedades .path
e .name
indicando o caminho para pesquisar e o nome a ser correspondido e pode fornecer outro contexto relevante.
O que isso significa na prática é que para prover suporte à localização de metadados de pacotes de distribuição em outros locais fora do sistema de arquivos, crie uma subclasse Distribution
e implemente os métodos abstratos. Então, a partir de um localizador personalizado, retorne instâncias deste derivado de Distribution
no método find_distributions()
.