enum.verify: valida reglas de Enum en Python

Publicado el: 06/09/2026
Tempo de leitura: 6 minutos
Código Python validado con enum.verify

enum.verify es una herramienta de la biblioteca estándar de Python que valida reglas de una enumeración cuando se crea la clase. Permite detectar valores duplicados, huecos inesperados en secuencias numéricas y combinaciones inválidas de flags antes de que esos errores lleguen a producción. Resulta especialmente útil cuando las enums representan códigos persistentes, estados de una API, permisos, etapas de un flujo o valores de un protocolo.

La función se usa mediante el decorador verify() y verificadores incluidos como UNIQUE, CONTINUOUS y NAMED_FLAGS. En lugar de depender únicamente de pruebas separadas, la regla queda declarada junto a la propia enum. Si no se cumple, Python genera un error durante la definición de la clase.

Por qué validar enumeraciones

Una enum puede convertirse en un contrato público. Dos nombres con el mismo valor pueden crear un alias accidental. Un número ausente puede romper un sistema externo que espera una secuencia completa. Una máscara compuesta puede incluir un bit que no tiene nombre y que resulta difícil de auditar.

Estos problemas suelen permanecer ocultos porque la clase continúa funcionando en operaciones comunes. La validación desplaza el fallo al inicio de la aplicación o a la fase de pruebas, donde es más sencillo encontrar la causa.

Valores únicos con UNIQUE

from enum import Enum, verify, UNIQUE

@verify(UNIQUE)
class Estado(Enum):
    PENDIENTE = 1
    PROCESANDO = 2
    COMPLETADO = 3

Todos los miembros tienen valores diferentes. Si dos nombres comparten el mismo número, la creación de la clase falla. Sin esta verificación, el segundo nombre normalmente se convertiría en un alias del primero.

@verify(UNIQUE)
class Estado(Enum):
    PENDIENTE = 1
    PROCESANDO = 2
    FINALIZADO = 2

Los aliases no siempre son incorrectos. Pueden mantener compatibilidad durante una migración. Sin embargo, deben ser intencionales, documentados y probados. En APIs y datos persistidos, un alias accidental crea ambigüedad en la serialización, los logs y las comparaciones.

Cuándo aceptar aliases

Un proyecto puede conservar un nombre antiguo para no romper clientes existentes. En ese caso, no uses UNIQUE o coloca la compatibilidad en una capa de conversión. Registra el motivo del alias, su periodo de soporte y el nombre canónico que debe aparecer en nuevas respuestas.

Muchas veces es más limpio aceptar el texto antiguo en un parser y convertirlo al miembro nuevo. Así, el modelo interno continúa siendo estricto.

Secuencias continuas con CONTINUOUS

from enum import IntEnum, verify, CONTINUOUS

@verify(CONTINUOUS)
class Prioridad(IntEnum):
    BAJA = 1
    MEDIA = 2
    ALTA = 3

CONTINUOUS comprueba que todos los enteros entre el valor mínimo y el máximo están presentes. Una secuencia con 1, 2 y 4 falla porque falta el 3. La regla es útil para niveles ordenados, etapas contiguas, índices o rangos compactos de un protocolo.

No debe aplicarse cuando los huecos forman parte del contrato. Los códigos HTTP, por ejemplo, no son continuos. Algunos sistemas reservan intervalos para extensiones futuras. La validación debe reflejar el significado del dominio, no solo una preferencia estética.

Ejemplo de hueco detectado

@verify(CONTINUOUS)
class Etapa(IntEnum):
    INICIO = 1
    VALIDACION = 2
    PUBLICACION = 4

Si el valor 3 se omitió por error, la clase falla inmediatamente. Si el hueco está reservado, elimina la regla y documenta el intervalo para evitar correcciones equivocadas en el futuro.

Flags con nombres mediante NAMED_FLAGS

from enum import Flag, verify, NAMED_FLAGS

@verify(NAMED_FLAGS)
class Permiso(Flag):
    LEER = 1
    ESCRIBIR = 2
    ELIMINAR = 4
    ADMIN = LEER | ESCRIBIR | ELIMINAR

NAMED_FLAGS valida que los aliases y las máscaras compuestas utilicen bits representados por miembros con nombre. Una combinación con un bit desconocido puede otorgar una capacidad que la aplicación no sabe describir correctamente.

Para los miembros básicos, utiliza potencias de dos. Construye combinaciones con el operador |. De esta manera, los logs, las auditorías y las comprobaciones de permisos son más legibles.

Combinar verificaciones

from enum import IntEnum, verify, UNIQUE, CONTINUOUS

@verify(UNIQUE, CONTINUOUS)
class Nivel(IntEnum):
    PRINCIPIANTE = 1
    INTERMEDIO = 2
    AVANZADO = 3

El decorador acepta varias reglas. En este caso, los valores deben ser únicos y continuos. Combina verificaciones solo cuando cada una exprese un requisito real. Una regla demasiado estricta puede dificultar extensiones legítimas.

Fallos durante la importación

La validación ocurre al crear la clase, normalmente durante la importación del módulo. Por eso, una enum inválida puede impedir el inicio de la aplicación. Para errores de contrato, este comportamiento rápido es positivo. En sistemas de plugins o carga dinámica, conviene capturar y registrar el módulo responsable.

Incluye pruebas de importación en la integración continua. Son especialmente útiles cuando las enums se generan automáticamente o se modifican con frecuencia.

Elegir Enum, IntEnum y Flag

Enum ofrece miembros simbólicos sin comportamiento entero implícito. IntEnum facilita la interoperabilidad con sistemas numéricos. Flag representa combinaciones de bits. Elige el tipo más limitado que satisfaga la integración.

Si no necesitas comparar el miembro con enteros, prefiere Enum. Si un protocolo o sistema heredado exige números, usa IntEnum con cuidado. Para permisos combinables, usa Flag o IntFlag. verify refuerza estas decisiones, pero no sustituye un buen modelado.

APIs y bases de datos

Al persistir una enum, decide si guardarás el nombre o el valor. Los nombres son legibles, pero renombrarlos exige una migración. Los valores son compactos, aunque deben permanecer estables después de publicarse. UNIQUE evita colisiones accidentales en códigos almacenados.

En una API, serializa siempre de la misma forma. No devuelvas el nombre en un endpoint y el número en otro sin un contrato claro. Valida entradas desconocidas y convierte datos externos mediante una capa explícita.

Pruebas de enums verificadas

def test_contrato_estado():
    assert Estado.PENDIENTE.value == 1
    assert Estado.COMPLETADO.name == "COMPLETADO"

def test_prioridades_continuas():
    assert [item.value for item in Prioridad] == [1, 2, 3]

El decorador valida la estructura, mientras las pruebas protegen valores públicos, serialización, parsing y compatibilidad. Si otros sistemas almacenan los números, cualquier cambio debe considerarse una modificación de API.

Estrategia de migración

Antes de añadir verificadores a un proyecto existente, revisa aliases y huecos. Algunos valores extraños pueden ser parte de un contrato antiguo. Documenta el comportamiento actual, añade pruebas y decide cuáles irregularidades son errores y cuáles deben mantenerse.

Para renombrar un miembro, acepta temporalmente el nombre anterior en la entrada, migra los datos persistidos y utiliza únicamente el nombre canónico en nuevas salidas.

Buenas prácticas

Usa nombres descriptivos, no reutilices valores ya publicados, documenta huecos intencionales y conserva las enums cerca de la lógica del dominio. Mantén simples los flags básicos y crea combinaciones con nombre para conjuntos de permisos habituales.

En catálogos grandes administrados por una autoridad externa, genera la enum desde la fuente oficial y valida el resultado en CI. Guarda también la versión de la fuente para revisar cambios.

Recursos relacionados

Continúa con los artículos de Academify sobre diccionarios en Python, conjuntos en Python, clases en Python y dataclasses en Python. Consulta también la documentación oficial de enum y la PEP 435.

Conclusión

enum.verify convierte supuestos implícitos en comprobaciones ejecutables. UNIQUE evita aliases accidentales, CONTINUOUS detecta huecos numéricos no deseados y NAMED_FLAGS protege las máscaras contra bits sin nombre. Aplicadas según el dominio, estas reglas producen contratos más seguros para APIs, bases de datos, permisos, flujos y protocolos.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Grafo de dependencias y flujo de tareas con TopologicalSorter en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    TopologicalSorter: ordena dependencias sin ciclos

    Aprende TopologicalSorter en Python para ordenar dependencias, detectar ciclos y ejecutar pipelines secuenciales o paralelos con seguridad.

    Ler mais

    Tempo de leitura: 6 minutos
    06/09/2026
    Carpetas y directorios que representan os.fwalk en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    os.fwalk en Python: recorre directorios

    Aprende os.fwalk en Python para recorrer directorios con descriptores, reducir condiciones de carrera y manipular archivos con mayor seguridad.

    Ler mais

    Tempo de leitura: 5 minutos
    05/09/2026
    Desarrollador revisando código Python y métodos sobrescritos
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    typing.override: valida sobrescrituras de métodos

    Aprende typing.override en Python para validar sobrescrituras, firmas compatibles, herencia y refactorizaciones con análisis estático.

    Ler mais

    Tempo de leitura: 6 minutos
    05/09/2026
    Desarrollador trabajando con colas e hilos en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    queue.SimpleQueue: cola FIFO segura entre hilos

    Aprende queue.SimpleQueue en Python para crear colas FIFO seguras entre hilos, workers y diseños productor-consumidor.

    Ler mais

    Tempo de leitura: 5 minutos
    04/09/2026
    Desarrollador trabajando con enums y código Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    StrEnum en Python: enums como strings

    Aprende StrEnum en Python para crear enums como strings, validar entradas, serializar JSON y organizar APIs y configuraciones.

    Ler mais

    Tempo de leitura: 5 minutos
    04/09/2026
    Carpetas y directorios para contextlib.chdir en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    contextlib.chdir: restaura directorios automáticamente

    Aprende contextlib.chdir en Python para cambiar directorios temporalmente, restaurar rutas y crear pruebas confiables sin errores de estado global.

    Ler mais

    Tempo de leitura: 6 minutos
    03/09/2026