mailbox en Python: buzones de correo

Publicado el: 12/08/2026
Tempo de leitura: 5 minutos
Documento y bandeja de entrada que representan buzones de correo con mailbox en Python

El módulo mailbox manipula buzones de correo almacenados en disco. Soporta Maildir, mbox, MH, Babyl y MMDF y presenta una interfaz parecida a un diccionario, donde las claves identifican mensajes. Es útil para migraciones, copias de seguridad, filtros locales, índices, herramientas forenses e integraciones con clientes de correo.

El módulo no descarga mensajes por IMAP ni envía correo por SMTP. Trabaja con formatos locales. Combínalo con el paquete email para interpretar cabeceras, MIME, adjuntos y cuerpos.

Elegir el formato

Maildir almacena cada mensaje en un archivo separado dentro de tmp, new y cur. Este diseño tolera mejor procesos independientes y normalmente no requiere un lock global. mbox y MMDF guardan muchos mensajes en un solo archivo y exigen locking cuidadoso.

Para un sistema nuevo con escritores concurrentes, Maildir suele ser más seguro. Para interoperar con archivos existentes, conserva el formato y sigue sus reglas.

Abrir un Maildir

import mailbox

buzon = mailbox.Maildir("correo", create=True)
print(len(buzon))

for mensaje in buzon:
    print(mensaje.get("Subject"))

La iteración por defecto devuelve representaciones de mensajes, no claves. Cada acceso genera un objeto nuevo. Modificarlo en memoria no actualiza el buzón hasta asignarlo otra vez a la clave.

Iterar por claves

for clave in buzon.iterkeys():
    mensaje = buzon.get_message(clave)
    print(clave, mensaje.get("From"))

Las claves solo tienen sentido para esa instancia y formato. Operaciones como MH.pack() pueden invalidarlas. No son identificadores globales permanentes.

Añadir un mensaje

from email.message import EmailMessage

mensaje = EmailMessage()
mensaje["From"] = "alice@example.com"
mensaje["To"] = "bob@example.com"
mensaje["Subject"] = "Informe"
mensaje.set_content("Contenido")

clave = buzon.add(mensaje)

add() acepta mensajes mailbox, objetos del paquete email, strings, bytes y archivos binarios. El contenido se copia; el buzón no conserva una referencia viva.

Reemplazar un mensaje

mensaje = buzon.get_message(clave)
mensaje.replace_header("Subject", "Informe revisado")
buzon[clave] = mensaje

Metadatos específicos, como flags, pueden conservarse o convertirse según la subclase. Revisa las reglas del formato.

Eliminar mensajes

buzon.remove(clave)
# del buzon[clave]
# buzon.discard(clave)

remove() y del generan KeyError si falta la clave. discard() ignora el caso, útil cuando otro proceso puede eliminar mensajes.

Locking en formatos de archivo único

Adquiere el lock antes de leer y modificar mbox, MMDF y otros formatos que lo requieren.

buzon = mailbox.mbox("archivo.mbox")
buzon.lock()
try:
    for clave, mensaje in buzon.iteritems():
        if mensaje.get("Subject") == "Borrar":
            buzon.discard(clave)
    buzon.flush()
finally:
    buzon.unlock()
    buzon.close()

Sin locking, dos procesos pueden perder cambios o corromper todo el archivo. Un conflicto puede generar ExternalClashError.

Concurrencia en Maildir

Maildir evita el lock global porque cada mensaje es un archivo. Aun así, múltiples threads que escriben en el mismo buzón pueden producir colisiones de nombres si la aplicación no las coordina.

Usa un lock de aplicación para writers locales y prueba en el sistema de archivos real, especialmente si es almacenamiento de red.

Flags de Maildir

Python 3.13 añadió métodos rápidos para consultar y cambiar flags sin abrir el mensaje completo.

flags = buzon.get_flags(clave)
buzon.add_flag(clave, "S")
buzon.remove_flag(clave, "F")
buzon.set_flags(clave, "RS")

Un objeto MaildirMessage ya cargado no se sincroniza automáticamente con cambios hechos a nivel del buzón. Recárgalo.

Información y carpetas Maildir

get_info() y set_info(), también desde Python 3.13, acceden a la sección info del nombre del archivo.

print(buzon.list_folders())
archivados = buzon.add_folder("Archivados.2026")
subbuzon = buzon.get_folder("Archivados.2026")

El estilo Courier utiliza puntos para representar niveles lógicos.

Limpiar entregas temporales

Maildir.clean() elimina archivos antiguos de tmp según la convención del formato. Úsalo con cuidado en almacenamiento inestable.

Leer bytes, texto o archivo

datos = buzon.get_bytes(clave)
texto = buzon.get_string(clave)

with buzon.get_file(clave) as archivo:
    primera = archivo.readline()

get_bytes() es mejor para procesamiento fiel. get_string() produce una representación limpia de siete bits. Usa un parser binario con política explícita.

Factory personalizada

from email import policy
from email.parser import BytesParser

def fabrica(archivo):
    return BytesParser(policy=policy.default).parse(archivo)

buzon = mailbox.Maildir("correo", factory=fabrica)

Una factory puede devolver objetos modernos del paquete email o solo metadatos para reducir memoria.

mbox y la línea From

mbox separa mensajes con líneas que comienzan por From . Las apariciones en el cuerpo se escapan al guardar. Existen variantes incompatibles, por lo que las migraciones deben probarse.

Los métodos de mbox aceptan from_ para incluir o quitar la línea Unix From.

MH y secuencias

MH guarda un mensaje por archivo y admite secuencias nombradas.

buzon = mailbox.MH("mh")
secuencias = buzon.get_sequences()
secuencias["importantes"] = ["1", "3"]
buzon.set_sequences(secuencias)

pack() renumera mensajes y deja inválidas las claves anteriores.

Migrar entre formatos

origen = mailbox.mbox("origen.mbox")
destino = mailbox.Maildir("destino", create=True)

origen.lock()
try:
    for mensaje in origen:
        destino.add(mensaje)
finally:
    origen.unlock()
    origen.close()
    destino.close()

Antes de migrar, copia el origen, cuenta mensajes, registra hashes y define cómo convertir flags. Valida adjuntos y abre el resultado con otro cliente.

Modificar durante la iteración

Los mensajes añadidos después de crear el iterador no aparecen. Los eliminados antes de ser alcanzados se omiten. Procesos concurrentes aún pueden invalidar claves.

Contenido no confiable

El correo puede incluir cabeceras malformadas, MIME profundo, adjuntos enormes, nombres peligrosos y HTML activo. No ejecutes adjuntos ni renderices HTML sin sanitizar. Limita tamaño, partes, profundidad y descompresión.

Backups y flush

Antes de cambios destructivos en mbox, crea una copia y verifica espacio. flush() escribe cambios pendientes, pero no sustituye un plan de recuperación.

Maildir aísla mejor las operaciones, aunque migraciones grandes necesitan checkpoints y capacidad de reanudación.

Exportar metadatos

import json
import mailbox

buzon = mailbox.Maildir("correo")
registros = []
for clave in buzon.iterkeys():
    msg = buzon.get_message(clave)
    registros.append({
        "key": str(clave),
        "from": msg.get("From"),
        "to": msg.get("To"),
        "subject": msg.get("Subject"),
        "date": msg.get("Date"),
        "flags": msg.get_flags(),
    })

with open("indice.json", "w", encoding="utf-8") as f:
    json.dump(registros, f, ensure_ascii=False, indent=2)

Las cabeceras no son confiables, pueden repetirse y contener fechas inválidas.

Errores frecuentes

  • Modificar mbox sin lock.
  • Esperar que editar Message actualice el buzón.
  • Usar claves como IDs permanentes.
  • Cerrar el buzón mientras se usa un archivo devuelto.
  • Confundir almacenamiento local con IMAP.
  • Ignorar variantes mbox.
  • Procesar adjuntos sin límites.

Buenas prácticas

  • Prefiere Maildir para escritura concurrente.
  • Bloquea formatos que lo requieren.
  • Llama flush() y close().
  • Haz backup antes de cambios masivos.
  • Parsea bytes con política explícita.
  • Valida conteos, flags y hashes tras migrar.
  • Limita todo contenido no confiable.

Guías relacionadas

Continúa con quopri en Python, mimetypes en Python, fileinput en Python, filecmp en Python y ExitStack en Python.

Consulta la documentación oficial de mailbox y la documentación del paquete email.

Conclusión

mailbox ofrece una interfaz uniforme sobre formatos locales muy distintos. Su uso fiable depende de entender locking, copia de mensajes, duración de claves, diferencias de formato y riesgos del contenido. Para nuevos almacenes concurrentes, Maildir suele ser la base más segura.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Editor de texto que representa formato con textwrap en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    textwrap en Python: formatea textos

    Aprende textwrap en Python para dividir, rellenar, acortar, indentar y quitar sangrías con control de ancho, espacios y palabras largas.

    Ler mais

    Tempo de leitura: 5 minutos
    10/08/2026
    Carpeta y lupa que representan filtros de nombres con fnmatch en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    fnmatch en Python: filtra nombres de archivos

    Aprende fnmatch en Python para filtrar nombres de archivos con comodines, controlar mayúsculas, excluir patrones y distinguir glob de regex.

    Ler mais

    Tempo de leitura: 5 minutos
    10/08/2026
    Monitor con datos binarios que representa arrays numéricos compactos en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    array en Python: números compactos

    Aprende array en Python para almacenar números compactos, usar archivos binarios, byte order, memoryview y buffers seguros.

    Ler mais

    Tempo de leitura: 5 minutos
    10/08/2026
    Círculo cromático que representa conversiones RGB, HSV y HLS con colorsys en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    colorsys en Python: RGB, HSV y HLS

    Aprende colorsys en Python para convertir colores entre RGB, HSV, HLS y YIQ, crear paletas y evitar errores de escala

    Ler mais

    Tempo de leitura: 5 minutos
    09/08/2026
    Icono de configuración que representa archivos plist con plistlib en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    plistlib en Python: archivos plist

    Aprende plistlib en Python para leer y escribir archivos plist XML y binarios, validar datos y manejar fechas, bytes y

    Ler mais

    Tempo de leitura: 6 minutos
    08/08/2026
    Candado digital que representa credenciales por host con netrc en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    netrc en Python: credenciales por host

    Aprende netrc en Python para leer credenciales por host, validar permisos, tratar errores e integrar clientes de red de forma

    Ler mais

    Tempo de leitura: 7 minutos
    08/08/2026