importlib.metadata: versões e plugins

Publicado em: 27/08/2026
Tempo de leitura: 9 minutos
Close-up of a hand pointing at audio editing software on a monitor in a recording studio.

O módulo importlib.metadata lê metadados de distribuições Python instaladas sem precisar importar os pacotes. Ele permite consultar versão, nome, autor, requisitos, arquivos, entry points e o relacionamento entre distribuições e módulos importáveis. É útil em CLIs de diagnóstico, sistemas de plugins, relatórios de suporte, verificações de compatibilidade, inventários e observabilidade.

Uma distribuição instalada não é a mesma coisa que um módulo. O comando pip install beautifulsoup4, por exemplo, instala uma distribuição cujo pacote importável principal tem outro nome. A API trabalha com metadados de instalação, normalmente presentes em diretórios .dist-info ou .egg-info.

Consulte uma versão

A função version() retorna a versão declarada pela distribuição.

from importlib.metadata import version

print(version("requests"))

Use o nome da distribuição, não necessariamente o nome usado no import.

PackageNotFoundError

Quando a distribuição não está instalada, a API lança PackageNotFoundError.

from importlib.metadata import PackageNotFoundError, version

try:
    versao = version("meu-plugin")
except PackageNotFoundError:
    versao = None

Diferencie pacote ausente de metadados inválidos ou ambiente incorreto.

Não importe apenas para obter a versão

Muitos pacotes expõem __version__, mas importá-los pode ser lento ou produzir side effects.

importlib.metadata.version() lê a informação instalada sem executar o código da biblioteca.

O nome da distribuição

Nomes são comparados segundo regras de normalização do ecossistema de packaging.

Hífens, underscores e diferenças de maiúsculas podem ser normalizados. Preserve o nome canônico exibido nos metadados para relatórios.

metadata

metadata(name) devolve uma estrutura semelhante a headers de e-mail.

from importlib.metadata import metadata

meta = metadata("requests")
print(meta["Name"])
print(meta["Version"])
print(meta.get("Summary"))

Nem todo campo é obrigatório ou preenchido corretamente por todas as distribuições.

Campos repetidos

Alguns metadados, como classifiers e requisitos, podem ocorrer várias vezes.

Use métodos adequados da estrutura retornada para recuperar todos os valores, em vez de presumir uma única string.

Texto longo

Metadados podem incluir descrição extensa. Não registre o objeto inteiro em logs de produção.

Selecione campos necessários e limite tamanho.

requires

requires(name) retorna requisitos declarados pela distribuição.

from importlib.metadata import requires

for requisito in requires("requests") or []:
    print(requisito)

As strings seguem a sintaxe de requisitos do packaging, podendo incluir versões, extras e environment markers.

Analise requisitos com packaging

Não divida strings manualmente. Use packaging.requirements.Requirement.

from packaging.requirements import Requirement

req = Requirement('urllib3<3,>=1.21.1')
print(req.name, req.specifier)

Markers precisam ser avaliados no ambiente correto.

Dependência declarada não significa importada

Um requisito pode ser opcional, específico de plataforma ou usado apenas por uma feature.

Para módulos realmente carregados, combine metadados com testes e análise de imports.

files

files(name) lista arquivos registrados na distribuição.

from importlib.metadata import files

for arquivo in files("requests") or []:
    print(arquivo)

O resultado pode ser None quando a instalação não possui um registro completo.

PackagePath

Itens retornados oferecem informações e métodos para localizar o arquivo.

for item in files("meu-pacote") or []:
    caminho = item.locate()
    print(caminho)

Verifique existência e não presuma que todo item ainda está presente em uma instalação modificada.

Hashes e tamanhos

Registros de arquivos podem incluir hash e tamanho, dependendo da distribuição.

Esses valores ajudam em auditorias, mas não substituem uma política completa de verificação de integridade e assinatura.

distribution

distribution(name) retorna um objeto Distribution.

from importlib.metadata import distribution

dist = distribution("requests")
print(dist.version)
print(dist.metadata["Name"])

O objeto centraliza acesso a metadados, arquivos, requisitos e entry points.

locate_file

Um objeto Distribution pode localizar um caminho relativo da instalação.

caminho = dist.locate_file("requests/__init__.py")

Valide o resultado antes de abrir. Instalações editáveis e layouts especiais podem apontar para fora de site-packages.

distributions

distributions() percorre distribuições visíveis no ambiente.

from importlib.metadata import distributions

for dist in distributions():
    print(dist.metadata.get("Name"), dist.version)

Ordene o resultado e limite campos para um inventário reproduzível.

Inventário do ambiente

Um relatório útil inclui nome, versão, origem e talvez hash de arquivos críticos.

Não publique automaticamente o inventário completo; ele pode revelar componentes internos e superfície de ataque.

Ambientes virtuais

A API vê distribuições disponíveis ao interpretador atual.

Execute com o mesmo sys.executable da aplicação. Consultar pelo Python global gera um inventário diferente do venv.

Instalações editáveis

Editable installs possuem metadados instalados, mas o código pode apontar para um checkout.

Relatórios devem distinguir artefato imutável de ambiente de desenvolvimento.

packages_distributions

packages_distributions() mapeia nomes importáveis de topo para distribuições.

from importlib.metadata import packages_distributions

mapa = packages_distributions()
print(mapa.get("bs4"))

Um módulo pode ser fornecido por mais de uma distribuição, especialmente em namespaces.

Módulo versus distribuição

Use esse mapeamento ao relacionar resultados de modulefinder no Python com versões instaladas.

Não tente deduzir o nome da distribuição apenas capitalizando o import.

entry_points

Entry points são declarações de extensões, comandos e plugins instalados.

from importlib.metadata import entry_points

plugins = entry_points(group="minhaapp.plugins")
for ep in plugins:
    print(ep.name, ep.value)

A forma de seleção evoluiu entre versões; use a API da versão mínima declarada.

Grupos

Um grupo cria um namespace lógico, como console_scripts ou minhaapp.plugins.

Escolha um nome de grupo específico da organização para evitar conflitos.

EntryPoint

Cada entry point possui nome, grupo e valor. O valor normalmente referencia um módulo e objeto.

for ep in plugins:
    print(ep.group, ep.name, ep.value)

Você pode inspecionar metadados sem carregar o plugin.

load

EntryPoint.load() importa o módulo e retorna o objeto declarado.

plugin_factory = ep.load()
plugin = plugin_factory()

Essa chamada executa importação e pode produzir side effects ou falhar.

Não carregue todos os plugins automaticamente

Filtre por configuração, compatibilidade, autorização e versão antes de chamar load().

Plugins de terceiros devem ser isolados ou executados com privilégios adequados ao risco.

Duplicatas de entry point

Duas distribuições podem declarar o mesmo nome no mesmo grupo.

Defina uma política explícita: erro, prioridade configurada ou seleção por distribuição. Não dependa da ordem do ambiente.

Versão da API de entry points

APIs anteriores retornavam estruturas diferentes e usavam métodos de seleção distintos.

Centralize a compatibilidade e teste em todas as versões suportadas.

Console scripts

O grupo console_scripts define comandos instalados por ferramentas de packaging.

Inspecionar entry points permite diagnosticar por que uma CLI não foi criada ou qual objeto deveria ser chamado.

Não execute console scripts com load sem política

Um entry point de console foi projetado para ser chamado como comando, com argumentos e código de saída.

Para fidelidade, use o executável instalado ou um subprocesso, em vez de chamar o objeto arbitrariamente.

Metadados de versão e compatibilidade

Compare versões com packaging.version.Version, não como strings.

from packaging.version import Version

if Version(version("meu-plugin")) < Version("2.0"):
    raise RuntimeError("plugin antigo")

Strings lexicográficas tratam 10 e 2 incorretamente.

Requisitos e markers

Environment markers podem depender de Python, plataforma, implementação e extras.

Avalie-os com a biblioteca packaging e o ambiente de destino.

Extras

Extras representam conjuntos opcionais de dependências, como pacote[postgres].

Os metadados não garantem que o extra foi instalado como intenção; mostram requisitos e distribuições presentes.

Licenças

Campos de licença e classifiers ajudam em inventários, mas podem estar ausentes, ambíguos ou desatualizados.

Para compliance, use uma ferramenta dedicada e revisão das licenças reais.

URLs do projeto

Metadados podem incluir homepage, repositório, documentação e issue tracker.

Não confie em URLs de uma distribuição desconhecida como destino seguro para automação.

Cache

Consultas repetidas podem ser cacheadas pela aplicação quando o ambiente não muda.

Instalar ou remover distribuições durante o processo torna caches antigos. Em produção, ambientes imutáveis simplificam a política.

Performance

Consultar uma versão é barato em uso comum, mas enumerar todas as distribuições e arquivos pode ser custoso.

Faça inventários no startup ou sob demanda, não em cada request.

Não dependa de ordem

A ordem de distributions(), files e entry points não deve definir comportamento.

Ordene explicitamente e resolva conflitos por política.

Metadados incompletos

Instalações antigas, manuais ou corrompidas podem não possuir todos os registros.

Use fallbacks claros e marque o ambiente como não verificável quando campos críticos faltam.

Pacotes da biblioteca padrão

A maioria dos módulos da standard library não corresponde a distribuições instaladas consultáveis por nome.

Use sysconfig e a versão do Python para identificar a biblioteca padrão.

Distribuições vendorizadas

Uma aplicação pode incluir código de terceiros dentro do próprio pacote sem metadados separados.

importlib.metadata não detecta automaticamente componentes vendorizados como distribuições independentes.

Containers

Gere um inventário durante o build e valide no runtime final.

Multi-stage builds podem instalar pacotes em uma etapa diferente; consulte a imagem que realmente será executada.

SBOM

Os metadados ajudam a construir uma Software Bill of Materials, mas uma SBOM completa precisa considerar bibliotecas nativas, sistema operacional, arquivos vendorizados e hashes.

Use formatos e ferramentas de SBOM apropriados.

Segurança

Listar versões pode ajudar um operador, mas também revela componentes a um atacante.

Proteja endpoints de diagnóstico e não exponha inventários completos publicamente.

Metadados não são confiança

Nome, versão e autor são declarações do pacote instalado.

Verifique origem, assinatura, hash e índice confiável conforme a política de supply chain.

Plugins e isolamento

Entry points facilitam descoberta, mas load() executa código.

Carregue somente plugins aprovados e considere processos separados para extensões de terceiros.

Observabilidade

Inclua versões de componentes principais em logs de startup ou métricas com cardinalidade controlada.

Não adicione todas as distribuições como labels de métricas.

Relatórios de suporte

Um comando de diagnóstico pode produzir ambiente, Python, plataforma e versões selecionadas.

Ofereça opção de redigir paths, nomes internos e dados do sistema antes do compartilhamento.

Integração com pkgutil

pkgutil descobre módulos oferecidos pelo sistema de importação; importlib.metadata descreve distribuições instaladas e plugins declarados.

Veja pkgutil no Python.

Integração com importlib.resources

Depois de identificar uma distribuição ou plugin, recursos devem ser acessados pela âncora do pacote.

Veja importlib.resources no Python.

Testes

Crie distribuições fixture ou instale wheels de teste. Cubra pacote ausente, versão, requisitos, files ausente, entry points duplicados, editable install e namespace packages.

Não dependa das distribuições instaladas na máquina do desenvolvedor.

Compatibilidade

O módulo entrou na biblioteca padrão em versões modernas e continuou evoluindo. Para versões antigas, existe o backport importlib_metadata.

Centralize imports e diferenças de API em uma camada do projeto.

Erros comuns

Os erros mais frequentes são usar nome de import em vez da distribuição, importar para obter versão, comparar versões como strings, chamar load() em todo plugin, depender da ordem de entry points, presumir metadados completos, enumerar tudo por request e expor inventários publicamente.

Conclusão

importlib.metadata consulta versões, requisitos, arquivos, distribuições e entry points sem importar o código correspondente. Use version() para verificações simples, distribution() para detalhes e entry_points() para plugins declarados.

Trate metadados como informação, não confiança, resolva nomes de módulo e distribuição corretamente e carregue plugins apenas depois de validar. Consulte a documentação oficial de importlib.metadata e o artigo de modulefinder no Python.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Neatly arranged binders and magazines on library shelves showcasing organization.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    importlib.resources: leia arquivos de pacotes

    Aprenda importlib.resources no Python para ler templates, dados e arquivos de pacotes com Traversable, files e as_file em wheels e

    Ler mais

    Tempo de leitura: 8 minutos
    27/08/2026
    Close-up view of a computer screen displaying code in a software development environment.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    runpy no Python: execute módulos e scripts

    Aprenda runpy no Python para executar módulos e scripts, controlar __main__, run_path, alter_sys, namespaces, testes e isolamento.

    Ler mais

    Tempo de leitura: 8 minutos
    27/08/2026
    A laptop screen showing a code editor with visible programming code in a dimly lit environment.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    pkgutil no Python: descubra pacotes

    Aprenda pkgutil no Python para listar módulos, percorrer pacotes, descobrir plugins, consultar importers e ler recursos com segurança.

    Ler mais

    Tempo de leitura: 7 minutos
    27/08/2026
    A developer typing code on a laptop with a Python book beside in an office.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    modulefinder no Python: descubra imports

    Aprenda modulefinder no Python para descobrir imports, dependências transitivas, módulos ausentes, paths, plugins e limitações da análise estática.

    Ler mais

    Tempo de leitura: 9 minutos
    27/08/2026
    Vivid close-up of code on a computer screen showcasing programming details.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    py_compile no Python: compile um arquivo

    Aprenda py_compile no Python para compilar um arquivo, controlar .pyc, dfile, otimização, invalidação por hash e erros de build.

    Ler mais

    Tempo de leitura: 8 minutos
    27/08/2026
    Detailed view of programming code in a dark theme on a computer screen.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    compileall no Python: gere bytecode .pyc

    Aprenda compileall no Python para gerar .pyc, validar sintaxe, compilar em paralelo, controlar otimização, paths e builds reproduzíveis.

    Ler mais

    Tempo de leitura: 9 minutos
    27/08/2026