getaddresses strict: valide listas de e-mail

Publicado em: 17/10/2026
Tempo de leitura: 5 minutos
Validação de endereços de e-mail com getaddresses strict no Python

O parâmetro strict de email.utils.getaddresses ajuda a analisar listas de endereços de e-mail com regras mais rigorosas. Ele é útil quando uma aplicação recebe cabeçalhos como To, Cc ou Reply-To e precisa rejeitar entradas malformadas em vez de tentar corrigi-las silenciosamente. Neste guia, você vai entender quando usar o modo estrito, como validar resultados, quais erros ainda precisam de tratamento adicional e como integrar essa função a sistemas reais.

O que faz getaddresses

getaddresses recebe uma sequência de strings e devolve pares no formato (nome, endereço). A função interpreta nomes de exibição, vírgulas, aspas e outros elementos da sintaxe de cabeçalhos. O uso básico é direto:

from email.utils import getaddresses

cabecalhos = [
    'Ana <ana@example.com>, Bruno <bruno@example.com>'
]

for nome, endereco in getaddresses(cabecalhos, strict=True):
    print(nome, endereco)

Com strict=True, o parser evita aceitar diversas construções inválidas que versões antigas toleravam. Isso melhora a previsibilidade, principalmente quando os dados vêm de formulários, integrações ou mensagens externas.

Por que o modo estrito importa

Um parser permissivo pode transformar uma entrada ruim em um resultado aparentemente válido. Isso é perigoso porque a aplicação pode enviar mensagens para um destinatário diferente do esperado, registrar dados inconsistentes ou aceitar conteúdo criado para confundir filtros. O modo estrito reduz esse risco ao exigir uma estrutura mais próxima da especificação.

Mesmo assim, getaddresses não substitui uma política completa de validação. Ele analisa a sintaxe do cabeçalho, mas não confirma se o domínio existe, se a caixa postal recebe mensagens ou se o endereço pertence ao usuário. Por isso, combine parsing, validação de domínio, confirmação por e-mail e limites de negócio.

Validando o resultado

Depois do parsing, trate campos vazios e resultados inesperados:

from email.utils import getaddresses


def extrair_destinatarios(valores: list[str]) -> list[str]:
    resultado = []

    for nome, endereco in getaddresses(valores, strict=True):
        endereco = endereco.strip()
        if not endereco or '@' not in endereco:
            raise ValueError('Endereço inválido')
        resultado.append(endereco)

    if not resultado:
        raise ValueError('Nenhum destinatário válido')

    return resultado

Essa verificação é simples, mas deixa clara uma regra importante: nunca confie somente na quantidade de pares devolvidos. Confirme que o endereço não está vazio, aplique seus limites e normalize apenas o necessário.

Não normalize demais

Transformar tudo para minúsculas pode parecer conveniente, mas a parte local de um endereço é tecnicamente sensível a maiúsculas em alguns servidores. Na prática, muitos provedores ignoram essa diferença, porém uma aplicação genérica deve preservar o valor original e usar uma versão normalizada apenas para comparação interna.

Também evite remover caracteres válidos, como sinais de mais, pontos ou sublinhados. Um filtro agressivo pode alterar um endereço correto. Para aprender mais sobre tratamento seguro de strings, veja o conteúdo sobre Python e os guias de Python avançado.

Separando parsing de autorização

Uma boa arquitetura separa três etapas: interpretar o cabeçalho, validar o endereço e decidir se ele pode ser usado. Por exemplo, um sistema corporativo pode aceitar apenas domínios autorizados. Essa regra não pertence ao parser.

DOMINIOS_PERMITIDOS = {'example.com', 'empresa.com.br'}


def dominio_permitido(endereco: str) -> bool:
    _, dominio = endereco.rsplit('@', 1)
    return dominio.lower() in DOMINIOS_PERMITIDOS

Essa separação facilita testes e reduz erros. O parser cuida da sintaxe; sua aplicação cuida das regras de segurança e negócio.

Tratando entradas vindas da web

Em formulários, limite o tamanho total do campo e a quantidade de endereços antes de processar. Uma lista enorme pode consumir tempo e memória desnecessários. Também registre falhas de parsing sem gravar dados sensíveis completos nos logs.

Quando o sistema envia mensagens, mantenha os destinatários em estruturas separadas para To, Cc e Bcc. Não concatene tudo em uma única string depois da validação. Isso reduz confusões e facilita auditoria.

Exemplo com dataclass

from dataclasses import dataclass
from email.utils import getaddresses

@dataclass(frozen=True)
class Destinatario:
    nome: str
    endereco: str


def parse_destinatarios(valores: list[str]) -> list[Destinatario]:
    itens = []
    for nome, endereco in getaddresses(valores, strict=True):
        if not endereco or '@' not in endereco:
            raise ValueError(f'Entrada inválida: {nome!r}')
        itens.append(Destinatario(nome.strip(), endereco.strip()))
    return itens

Uma estrutura imutável ajuda a evitar alterações acidentais depois da validação. Esse padrão combina bem com APIs, filas e serviços de envio.

Testes importantes

Crie testes para endereços simples, nomes com espaços, nomes entre aspas, múltiplos destinatários, entradas vazias, vírgulas extras e strings malformadas. Teste também limites de tamanho e duplicatas.

def test_destinatario_valido():
    itens = parse_destinatarios(['Ana <ana@example.com>'])
    assert itens[0].endereco == 'ana@example.com'


def test_destinatario_invalido():
    try:
        parse_destinatarios(['entrada sem endereco'])
    except ValueError:
        pass
    else:
        raise AssertionError('Era esperado ValueError')

Para aprofundar seus testes, consulte também os artigos de testes e o material sobre automação.

Compatibilidade de versões

Antes de usar o argumento strict, confirme a versão mínima do Python adotada pelo projeto. Bibliotecas distribuídas para ambientes antigos podem precisar de um caminho alternativo. Uma abordagem segura é declarar explicitamente a versão mínima no pyproject.toml e cobrir o comportamento no CI.

Evite capturar TypeError silenciosamente para tentar novamente sem strict, porque isso pode esconder erros reais. Se a compatibilidade for obrigatória, isole a decisão em uma função pequena e documentada.

Segurança e limites

O modo estrito reduz ambiguidades, mas não elimina riscos como injeção de cabeçalhos. Nunca aceite quebras de linha arbitrárias em campos controlados pelo usuário. Remova ou rejeite \r e \n antes de construir cabeçalhos e prefira as classes do pacote email, que aplicam regras próprias.

Também não use endereços analisados como comandos, caminhos ou identificadores sem validação adicional. Trate cada camada conforme seu contexto.

Referências oficiais

A documentação do módulo email.utils descreve o comportamento das funções auxiliares. Para compreender a sintaxe de mensagens, consulte também a RFC 5322.

Conclusão

email.utils.getaddresses(..., strict=True) é uma melhoria importante para aplicações que processam cabeçalhos de e-mail. Use-o para reduzir tolerância a entradas malformadas, mas mantenha validações adicionais, limites, testes e regras de autorização. A combinação de parsing estrito, modelos imutáveis e políticas claras produz sistemas mais seguros e previsíveis.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Código Python representando functools.Placeholder e argumentos posicionais
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    functools.Placeholder: argumentos flexíveis no partial

    Aprenda functools.Placeholder no Python 3.14 para preencher argumentos posicionais flexíveis com partial e partialmethod.

    Ler mais

    Tempo de leitura: 5 minutos
    17/10/2026
    Código em tela representando t-strings no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    T-strings no Python 3.14: templates estruturados

    Aprenda t-strings no Python 3.14, entenda Template e Interpolation e crie renderizadores estruturados, extensíveis e mais seguros.

    Ler mais

    Tempo de leitura: 5 minutos
    16/10/2026
    CPU e módulos de memória representando shared_memory track no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    shared_memory track: controle o resource tracker

    Aprenda o parâmetro track de multiprocessing.shared_memory no Python para controlar o resource tracker e evitar remoções prematuras.

    Ler mais

    Tempo de leitura: 6 minutos
    16/10/2026
    Unidade de armazenamento de dados representando compactação com compression.zstd no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    compression.zstd: streams e compressão segura

    Aprenda compression.zstd no Python para compactar arquivos e dados com velocidade, streaming, dicionários e segurança.

    Ler mais

    Tempo de leitura: 6 minutos
    15/10/2026
    Código em tela para diagnóstico de processos com sys.remote_exec no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    sys.remote_exec: diagnostique processos Python

    Aprenda sys.remote_exec no Python para diagnosticar processos em execução com scripts controlados, segurança e boas práticas.

    Ler mais

    Tempo de leitura: 6 minutos
    15/10/2026
    Código Python e configuração de variáveis de ambiente com os.reload_environ
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    os.reload_environ: riscos com threads e ambiente

    Aprenda os.reload_environ no Python para atualizar variáveis de ambiente alteradas externamente, validar configurações e evitar problemas com threads.

    Ler mais

    Tempo de leitura: 5 minutos
    14/10/2026