modulefinder no Python: descubra imports

Publicado em: 27/08/2026
Tempo de leitura: 9 minutos
A developer typing code on a laptop with a Python book beside in an office.

O módulo modulefinder analisa um script Python e tenta descobrir os módulos importados por ele e por suas dependências. Ele percorre code objects, segue instruções de importação, consulta caminhos de busca e produz um inventário que pode ajudar empacotadores, auditorias, ferramentas de build, visualizadores de dependências e diagnósticos de imports ausentes.

A análise não é perfeita. Python permite imports dinâmicos, plugins, alteração de sys.path, execução condicional e carregamento por nomes calculados em runtime. Portanto, o resultado deve ser tratado como aproximação estática baseada no código disponível, não como prova completa do que a aplicação carregará.

Crie um ModuleFinder

A classe principal é modulefinder.ModuleFinder.

from modulefinder import ModuleFinder

finder = ModuleFinder()
finder.run_script("app.py")

Depois da análise, o objeto contém módulos encontrados, referências ausentes e informações úteis para relatórios.

Liste os módulos encontrados

O atributo modules é um mapeamento de nome para objetos de módulo analisados.

for nome in sorted(finder.modules):
    modulo = finder.modules[nome]
    print(nome, modulo.__file__)

Nem todo módulo possui um arquivo tradicional. Builtins, extensões, namespaces e módulos especiais podem usar valores diferentes.

Use report

report() imprime um relatório legível.

finder.report()

É conveniente para investigação manual. Em automação, percorra os atributos e gere JSON ou outro formato estruturado.

Imports diretos e transitivos

Ao analisar um script, modulefinder segue imports dos módulos encontrados. O resultado inclui dependências transitivas, não apenas linhas presentes no arquivo inicial.

Uma biblioteca aparentemente pequena pode trazer uma árvore grande por meio de um único import.

O path de busca

O construtor aceita um path que corresponde aos diretórios usados para localizar módulos.

import sys
from modulefinder import ModuleFinder

finder = ModuleFinder(path=["src", *sys.path])
finder.run_script("src/app.py")

Use o mesmo ambiente e layout do runtime. Um path diferente pode encontrar outro pacote com o mesmo nome.

Ambientes virtuais

Execute a análise dentro do venv que contém as dependências reais. Misturar sys.path global e ambiente virtual produz resultados enganosos.

Registre sys.executable, versão do Python e paths usados.

src layout

Projetos que mantêm pacotes em src/ precisam incluir essa raiz explicitamente ou instalar o pacote no ambiente.

Prefira testar a distribuição instalada, pois isso reproduz melhor os metadados, namespaces e entry points reais.

Imports relativos

Imports relativos dependem do contexto do pacote. Analisar um arquivo interno como script isolado pode mudar o significado.

Quando possível, use o entry point real e a estrutura de pacote correta.

Imports condicionais

Um import dentro de um if pode ser detectado mesmo quando a condição nunca é verdadeira no ambiente atual.

if sys.platform == "win32":
    import winreg

O relatório pode incluir dependências opcionais de outras plataformas. Classifique-as em vez de removê-las cegamente.

try/except ImportError

Pacotes frequentemente tentam uma aceleração opcional e usam fallback.

try:
    import acelerador
except ImportError:
    import implementacao_python

Uma análise pode listar ambos ou marcar um como ausente. Isso não significa necessariamente que a aplicação está quebrada.

Imports dinâmicos

Chamadas como importlib.import_module(nome) usam uma string determinada em runtime. modulefinder pode não saber o valor.

modulo = importlib.import_module(config["backend"])

Empacotadores normalmente exigem uma lista explícita de hidden imports para esses casos.

__import__

O builtin __import__() também pode carregar nomes calculados.

Procure configurações, registries e convenções de plugins além do relatório estático.

Plugins

Sistemas de plugins descobrem módulos por entry points, diretórios, bancos ou configuração. Esses módulos podem não aparecer em imports do código principal.

Combine modulefinder com importlib.metadata.entry_points(), tema de um próximo artigo deste lote.

Pacotes namespace

Namespace packages podem ter partes em vários diretórios e distribuições. A análise precisa usar o ambiente instalado completo.

Não presuma que um único __file__ representa todo o namespace.

Extensões nativas

Módulos compilados podem aparecer como arquivos .so, .pyd ou equivalentes.

Modulefinder encontra a extensão como módulo, mas não descobre automaticamente bibliotecas nativas carregadas por ela, como DLLs e dependências do sistema.

Builtins

Módulos embutidos no interpretador não possuem um arquivo Python comum.

Um empacotador deve classificá-los como fornecidos pelo runtime, não copiá-los como fonte.

Módulos frozen

Implementações e executáveis podem incluir módulos frozen. O comportamento e a representação variam.

Teste o artefato final, pois a análise no ambiente de desenvolvimento pode não refletir o runtime congelado.

badmodules

O finder mantém informações de módulos que não foram localizados em determinados contextos.

Gere um relatório com quem tentou importar o nome. O mesmo módulo ausente pode ser opcional para um pacote e obrigatório para outro.

any_missing

Métodos de conveniência podem retornar nomes considerados ausentes.

faltantes = finder.any_missing()
print(faltantes)

Revise cada item antes de falhar o build, especialmente imports condicionais e opcionais.

any_missing_maybe

Algumas versões oferecem uma classificação entre ausentes definidos e possivelmente ausentes.

Essa distinção ajuda a priorizar investigação, mas continua sendo heurística.

Excludes

O construtor aceita uma lista de módulos excluídos.

finder = ModuleFinder(
    excludes=["tkinter", "tests"],
)

Exclusão diz à análise para ignorar módulos. Ela não prova que o programa nunca tentará importá-los.

Use excludes com política

Documente por que cada nome é excluído: plataforma, feature desativada, dependência de desenvolvimento ou substituição.

Adicione um teste de runtime para garantir que o caminho desativado não é alcançado.

replace_paths

replace_paths permite substituir prefixos de path em filenames registrados.

Isso pode tornar relatórios reproduzíveis e remover diretórios temporários do CI.

Privacidade de paths

Relatórios podem revelar nomes de usuário, home directories e estrutura interna do runner.

Normalize caminhos antes de publicar artefatos e restrinja acesso a inventários detalhados.

Debug

O parâmetro debug aumenta a saída interna da análise.

finder = ModuleFinder(debug=2)

Use em investigação local. Em CI, logs muito verbosos podem vazar paths e ficar difíceis de consultar.

load_file

Além de run_script(), APIs permitem carregar um arquivo específico em contextos controlados.

Escolha o método que represente corretamente se o arquivo é entry point ou módulo de pacote.

Code objects

Modulefinder examina bytecode e instruções relacionadas a import. Por isso, seu comportamento está ligado aos internals da versão do Python.

Use a versão do runtime de destino. Mudanças no compilador podem alterar detalhes da análise.

Integração com dis

Quando um import não é classificado como esperado, dis ajuda a mostrar as instruções geradas.

Leia dis no Python.

Código não executado

A análise pode encontrar imports em funções nunca chamadas, caminhos mortos e módulos de compatibilidade.

Modulefinder descreve dependências sintáticas possíveis, não frequência ou reachability em runtime.

Análise de cobertura

Combine o inventário estático com telemetria de imports em testes para identificar módulos realmente carregados.

Nem a cobertura dinâmica nem a análise estática são completas sozinhas. Juntas, reduzem lacunas.

Auditoria de dependências

O relatório pode ajudar a descobrir dependências transitivas inesperadas, mas não informa automaticamente distribuição, versão, licença ou vulnerabilidade.

Mapeie módulos para distribuições usando importlib.metadata.packages_distributions().

Standard library versus terceiros

Classifique módulos por origem: builtin, biblioteca padrão, pacote do projeto e site-packages.

Use sysconfig para identificar paths da biblioteca padrão. Veja sysconfig no Python.

Arquivos duplicados

Dois paths podem oferecer módulos com o mesmo nome. A ordem de busca define qual é encontrado.

Detecte shadowing e registre o arquivo selecionado. Um arquivo local chamado json.py pode ocultar a biblioteca padrão.

Zip imports

Dependências podem vir de arquivos ZIP no sys.path. Confirme se o finder e o empacotador suportam o loader usado.

Não dependa apenas de caminhos físicos normais.

Entry points diferentes

Uma aplicação pode ter CLI, worker, web server e tarefas agendadas com árvores diferentes.

Analise cada entry point e una os resultados, mantendo a origem de cada dependência.

Features opcionais

Crie perfis de build: mínimo, banco específico, GUI, cloud ou ciência de dados.

Uma única lista global pode incluir dependências enormes que não pertencem a todos os artefatos.

Formato estruturado

Converta o resultado em um formato estável.

resultado = {
    nome: {
        "arquivo": modulo.__file__,
    }
    for nome, modulo in finder.modules.items()
}

Ordene chaves para diffs reproduzíveis.

Grafos

O mapeamento de módulos sozinho não preserva necessariamente todas as arestas de import de forma pronta para visualização.

Instrumente a análise ou combine AST para construir um grafo explícito. Use graphlib no Python para ordenar dependências acíclicas quando apropriado.

Ciclos de import

Python permite ciclos em certas condições. Um inventário pode revelar módulos mutuamente dependentes, mas não decide se a inicialização será segura.

Teste imports em processo limpo e considere reorganizar código compartilhado.

Imports com side effects

Modulefinder tenta analisar, não executar a aplicação como um usuário faria. Mesmo assim, ferramentas de importação e loaders personalizados podem ter comportamentos específicos.

Execute a análise em ambiente isolado quando o projeto não for confiável.

Limites de recursos

Árvores grandes podem consumir tempo e memória. Defina limite de arquivos, tamanho e duração.

Cacheie resultados por hash do ambiente e entry point quando a análise for frequente.

Não analise uploads no processo web

Um serviço que recebe projetos deve usar worker separado, filesystem temporário e permissões reduzidas.

Valide archives antes de extraí-los e impeça paths que escapam da raiz.

CI

Uma pipeline pode comparar o inventário com uma baseline.

finder = ModuleFinder(path=paths)
finder.run_script(entrypoint)
nomes = sorted(finder.modules)

Revise mudanças intencionais em vez de falhar por toda diferença automática.

Testes

Inclua imports absolutos, relativos, condicionais, opcionais, dinâmicos, namespace packages, extensões, ZIP, módulos ausentes, paths duplicados e vários entry points.

Execute a suíte em cada plataforma suportada.

Erros comuns

Os erros mais frequentes são tratar o resultado como completo, ignorar imports dinâmicos, usar o venv errado, analisar um arquivo interno como script, falhar por dependência opcional, excluir sem teste, confundir módulo com distribuição e não testar o artefato empacotado.

Conclusão

modulefinder cria um inventário útil de imports diretos e transitivos a partir de um script. Configure o path correto, analise cada entry point, revise módulos ausentes e combine o resultado com plugins e observação dinâmica.

Trate a saída como aproximação e teste a aplicação final. Consulte a documentação oficial de modulefinder e o artigo de symtable no Python para entender escopos durante análise estática.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    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
    A classic MS-DOS terminal screen displayed on a laptop keyboard with vivid illumination.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    codeop no Python: compile comandos interativos

    Aprenda codeop no Python para detectar comandos completos, incompletos ou inválidos, criar REPLs e preservar flags de __future__ com segurança.

    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

    linecache no Python: leia linhas do código

    Aprenda linecache no Python para recuperar linhas de código, atualizar cache, integrar tracebacks, lidar com loaders e proteger caminhos.

    Ler mais

    Tempo de leitura: 9 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

    faulthandler no Python: diagnostique crashes

    Aprenda faulthandler no Python para diagnosticar crashes, deadlocks, timeouts, sinais fatais e travamentos com dumps de todas as threads.

    Ler mais

    Tempo de leitura: 10 minutos
    27/08/2026
    A close-up of a coin-operated telescope set against a beautiful cloudy sky, ideal for travel imagery.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    symtable no Python: analise escopos

    Aprenda symtable no Python para analisar escopos, locals, globals, parâmetros, imports, nonlocals, closures e namespaces usados pelo compilador.

    Ler mais

    Tempo de leitura: 9 minutos
    27/08/2026