marshal no Python: formato interno

Publicado em: 27/08/2026
Tempo de leitura: 8 minutos
A person typing on a laptop with a Python programming book visible, capturing technology and learning.

O módulo marshal lê e grava um formato binário interno usado principalmente pelo próprio Python para armazenar objetos de código em arquivos compilados. Ele consegue representar vários tipos básicos, como números, strings, bytes, tuplas, listas, sets, frozensets, dicionários e code objects, conforme a versão do interpretador.

Apesar de parecer uma alternativa rápida a JSON ou pickle, marshal não foi projetado como formato geral de persistência. A compatibilidade entre versões não é garantida para todos os tipos, o formato pode mudar e dados inválidos ou maliciosos não devem ser carregados. Seu uso ideal é restrito a ferramentas internas, experimentos controlados e compreensão da infraestrutura do Python.

marshal e arquivos .pyc

Quando um módulo Python é compilado, o interpretador cria um arquivo de bytecode em __pycache__. O conteúdo inclui um header gerenciado pela infraestrutura de import e uma representação do code object.

Não trate um arquivo .pyc inteiro como se fosse apenas o resultado de marshal.dumps(). O header contém metadados e pode mudar. Para ler bytecode, prefira ferramentas de import e módulos especializados.

Tipos básicos

O formato suporta um conjunto de tipos do próprio Python. Um exemplo simples:

import marshal

objeto = {
    "nome": "exemplo",
    "versao": 1,
    "valores": [1, 2, 3],
}

dados = marshal.dumps(objeto)
restaurado = marshal.loads(dados)
print(restaurado)

O round trip preserva valores suportados, mas não transforma o formato em contrato público estável.

dump e load

dump(value, file) grava em um arquivo binário e load(file) lê um objeto.

import marshal

with open("estado.bin", "wb") as arquivo:
    marshal.dump(objeto, arquivo)

with open("estado.bin", "rb") as arquivo:
    objeto = marshal.load(arquivo)

Abra sempre em modo binário. Um stream de texto tenta converter bytes e falha.

dumps e loads

dumps() devolve bytes, enquanto loads() recebe um objeto bytes-like.

payload = marshal.dumps((1, 2, 3))
valor = marshal.loads(payload)

Use essa forma quando o armazenamento, hash ou transporte já trabalha com bytes.

Versão do formato

A função de gravação aceita uma versão do formato. O valor padrão corresponde ao formato atual recomendado pelo interpretador.

payload = marshal.dumps(objeto, 4)

Não escolha uma versão apenas por ser numericamente maior. Consulte a documentação do Python executado e teste leitura no ambiente de destino.

Compatibilidade não é garantia de API

O Python tenta manter determinados valores simples legíveis entre versões de formato, mas code objects não são compatíveis entre versões do interpretador. Detalhes internos podem mudar.

Se os dados precisam sobreviver a upgrades, ser compartilhados entre serviços ou lidos por outra linguagem, use um formato documentado e versionado.

Code objects

Um code object representa bytecode, constantes, nomes, variáveis e metadados de execução de uma função ou módulo.

import marshal

codigo = compile("resultado = 2 + 3", "exemplo.py", "exec")
payload = marshal.dumps(codigo)
restaurado = marshal.loads(payload)
namespace = {}
exec(restaurado, namespace)
print(namespace["resultado"])

Executar o objeto restaurado executa código. Faça isso somente com dados produzidos e protegidos pelo próprio sistema.

allow_code

Nas APIs atuais, o parâmetro allow_code permite controlar se code objects podem ser serializados ou desserializados.

dados = marshal.dumps(objeto, allow_code=False)
valor = marshal.loads(dados, allow_code=False)

Desabilitar code objects reduz uma categoria de risco, mas não transforma entrada hostil em segura.

Dados não confiáveis

A documentação alerta para não carregar dados recebidos de fonte não confiável. Um payload inválido pode provocar comportamento indefinido, falha, consumo excessivo ou outros problemas.

Não use marshal.loads() em request HTTP, mensagem de fila pública, upload de usuário ou cache compartilhado sem uma fronteira forte de confiança.

Assinatura e integridade

Quando o formato é usado internamente, proteja o arquivo com permissões e, quando necessário, assinatura ou MAC. Verificar integridade ajuda a detectar alteração.

A assinatura não resolve incompatibilidade de versão e só é confiável se a chave e o emissor estiverem protegidos.

Limite de tamanho

Antes de ler, verifique o tamanho do arquivo ou mensagem. Estruturas grandes podem consumir memória e CPU.

from pathlib import Path

caminho = Path("estado.bin")
if caminho.stat().st_size > 10_000_000:
    raise ValueError("arquivo grande demais")

O limite deve refletir o caso real da aplicação.

Profundidade e recursão

Estruturas muito profundas podem exceder limites internos ou provocar erros. Não aumente limites de recursão apenas para aceitar payloads arbitrários.

Valide a estrutura lógica após a leitura e prefira dados rasos.

Tipos não suportados

Objetos de classes personalizadas, funções comuns, conexões, generators e muitos outros tipos não possuem representação marshal direta.

try:
    marshal.dumps(object())
except ValueError as erro:
    print(erro)

Não crie um sistema complexo de conversão apenas para forçar o uso do formato. JSON, dataclasses ou pickle controlado podem expressar melhor o domínio.

None e valores singleton

Valores como None, True e False são suportados. Após a carga, mantenha validações de tipo e schema.

O fato de o formato conseguir representar um valor não significa que ele seja válido para a aplicação.

Dicionários

Mappings serializados podem conter chaves e valores suportados. A ordem observável não deve ser usada como contrato do formato.

Para dados de configuração, prefira um schema explícito com nomes, tipos e versões.

Sets

Sets e frozensets podem ser suportados conforme o formato. Como não possuem ordem semântica, bytes gerados não devem ser usados como hash canônico de conteúdo.

Para assinatura determinística de dados, normalize a estrutura antes com uma especificação própria.

Floats e números complexos

O formato suporta tipos numéricos do Python, mas interoperabilidade com outra linguagem não é objetivo.

Se valores monetários ou decimais precisam de precisão e portabilidade, serialize strings ou inteiros segundo um schema explícito, em vez de depender de representação interna.

marshal versus pickle

Pickle suporta uma variedade maior de objetos e mecanismos de customização, como copyreg no Python. Ambos são formatos específicos do Python e não devem receber dados não confiáveis.

marshal é mais restrito e orientado ao interpretador, especialmente a code objects.

marshal versus JSON

JSON possui tipos mais limitados, mas é documentado, interoperável e adequado a APIs quando combinado com validação.

Use JSON para dados de negócio e comunicação. Use marshal apenas quando a ligação com internals do Python for uma exigência real.

marshal versus struct

struct empacota valores binários conforme um layout explícito. É melhor para protocolos e arquivos cujo formato precisa ser estável.

Marshal descreve objetos Python e não oferece um layout público apropriado para outras implementações.

Cache temporário

Um cache descartável criado e consumido pela mesma versão do Python pode ser um caso aceitável. O sistema deve conseguir apagar e reconstruir o cache quando a leitura falhar.

Nunca torne dados marshal a única cópia de informação importante.

Inclua metadados externos

Quando você controla um arquivo interno, guarde fora do payload a versão da aplicação, versão do Python, checksum e timestamp.

metadados = {
    "python": platform.python_version(),
    "schema": 1,
}

Esses dados ajudam a rejeitar caches incompatíveis antes da carga.

Escrita atômica

Grave primeiro em um arquivo temporário, faça flush quando necessário e substitua o destino com os.replace().

Uma interrupção durante escrita direta pode deixar um payload truncado que falhará depois.

Concorrência

Vários processos não devem sobrescrever o mesmo arquivo sem coordenação. Use locks, nomes por versão ou um sistema de cache apropriado.

Uma leitura simultânea durante substituição atômica normalmente vê a versão antiga ou nova, não um arquivo parcialmente escrito.

Erros de leitura

Capture erros esperados, descarte caches reconstruíveis e preserve diagnóstico.

try:
    valor = marshal.loads(payload)
except (EOFError, ValueError, TypeError) as erro:
    registrar_cache_invalido(erro)
    valor = reconstruir()

Não continue com estado parcialmente lido.

Auditoria

Operações de marshal podem emitir eventos de auditoria do Python. Ambientes controlados podem monitorar carga de objetos e code objects.

Audit hooks complementam isolamento e permissões, não os substituem.

Análise de bytecode

Para estudar code objects, combine compile(), marshal em ambiente controlado e o módulo dis. Não execute bytecode desconhecido.

O artigo sobre ast no Python mostra uma camada estrutural anterior ao bytecode.

Testes entre versões

Se um cache atravessa deployments, execute uma matriz com as versões de Python suportadas. Teste leitura de arquivo antigo, rejeição de incompatível e reconstrução automática.

Não confie apenas no round trip dentro do mesmo processo.

Observabilidade

Registre tamanho, versão da aplicação, versão do Python, duração e motivo da invalidação. Não registre os bytes completos, que podem conter código ou dados sensíveis.

Erros comuns

Os erros mais frequentes são usar marshal como banco de dados, ler payload externo, presumir compatibilidade de code objects, tratar .pyc como payload puro, executar code object restaurado sem confiança, omitir limites e manter somente uma cópia importante no formato.

Conclusão

marshal é uma ferramenta interna do ecossistema Python, adequada a code objects e caches descartáveis sob controle estrito. Use arquivos binários, valide tamanho e versão, proteja origem e reconstrua o cache quando houver incompatibilidade.

Para dados de aplicação, prefira formatos estáveis e schemas explícitos. Consulte a documentação oficial de marshal e a documentação de dis.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    A close-up view of fresh, green cucumbers ready for pickling and preservation in Estonia.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    copyreg no Python: personalize o pickle

    Aprenda copyreg no Python para personalizar pickle, registrar redutores, versionar estado, evitar conflitos globais e serializar com segurança.

    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

    reprlib no Python: representações seguras

    Aprenda reprlib no Python para resumir listas, strings e objetos recursivos, limitar logs e criar representações seguras e legíveis.

    Ler mais

    Tempo de leitura: 7 minutos
    27/08/2026
    A close-up shot showcasing the intricate scales of a snake, highlighting texture and color.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    graphlib no Python: ordenação topológica

    Aprenda graphlib no Python para ordenar dependências, detectar ciclos, executar tarefas prontas em paralelo e criar pipelines seguros.

    Ler mais

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

    weakref: evite reter objetos em caches

    Aprenda weakref no Python para referências fracas, caches, WeakSet, WeakMethod, finalize, callbacks e prevenção de retenção acidental.

    Ler mais

    Tempo de leitura: 8 minutos
    27/08/2026
    Young professional woman working on a laptop in an office setting, concentrating on her task.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    contextlib no Python: gerencie recursos

    Aprenda contextlib no Python com contextmanager, ExitStack, suppress, closing, asynccontextmanager e cleanup seguro de recursos.

    Ler mais

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

    ast no Python: analise código-fonte

    Aprenda ast no Python para analisar e transformar código, criar visitors, preservar posições, usar literal_eval e evitar riscos de execução.

    Ler mais

    Tempo de leitura: 7 minutos
    27/08/2026