assert_type y reveal_type: prueba inferencia de tipos

Publicado el: 29/08/2026
Tempo de leitura: 4 minutos
High-angle view of woman coding on a laptop, with a Python book nearby. Ideal for programming and tech content.

typing.assert_type y typing.reveal_type ayudan a comprender y probar la inferencia estática. reveal_type() pide al analizador que muestre el tipo inferido de una expresión. assert_type() declara el tipo esperado y convierte esa expectativa en una prueba estática que falla cuando cambia la inferencia.

Son herramientas útiles para bibliotecas, overloads, genéricos, Protocol, TypedDict, decoradores y funciones de refinamiento. Esta guía cubre exploración, pruebas automatizadas, CI, comportamiento de runtime, Any, tipos variádicos, Self y diferencias entre analizadores.

Qué hace reveal_type

from typing import reveal_type

valor = [1, 2, 3]
reveal_type(valor)

Un analizador puede informar list[int]. El diagnóstico aparece durante el análisis estático. El comportamiento de runtime es secundario y puede imprimir un mensaje.

Revelar expresiones intermedias

datos: dict[str, int | None] = {"a": 1}
valor = datos.get("a")
reveal_type(valor)

El resultado debería ser int | None. Eso explica por qué se necesita una comprobación antes de realizar aritmética.

Refinamiento por flujo

if valor is not None:
    reveal_type(valor)
    print(valor + 1)

Dentro de la rama, el tipo debería reducirse a int.

Qué hace assert_type

from typing import assert_type

resultado = len("python")
assert_type(resultado, int)

El analizador compara el tipo inferido con el esperado. En runtime, la función devuelve el primer argumento y no lo convierte ni valida.

assert_type no es isinstance

valor: object = 10
assert_type(valor, int)  # debería fallar estáticamente

El objeto concreto es entero, pero el tipo estático declarado es object. assert_type prueba la información estática, no el valor observado.

Probar una función genérica

from typing import TypeVar

T = TypeVar("T")

def primero(items: list[T]) -> T:
    return items[0]

assert_type(primero([1, 2]), int)
assert_type(primero(["a", "b"]), str)

Las pruebas confirman que el parámetro genérico se propaga al retorno.

Probar overloads

from typing import Literal, overload

@overload
def leer(*, binario: Literal[False] = False) -> str: ...
@overload
def leer(*, binario: Literal[True]) -> bytes: ...

def leer(*, binario: bool = False) -> str | bytes:
    return b"datos" if binario else "datos"

assert_type(leer(), str)
assert_type(leer(binario=True), bytes)

Cambiar el orden o las firmas puede degradar la inferencia. assert_type detecta la regresión sin ejecutar la función.

Probar Literal

modo = "rapido"
reveal_type(modo)

modo_literal: Literal["rapido"] = "rapido"
assert_type(modo_literal, Literal["rapido"])

Una variable mutable puede ampliarse a str, mientras que la anotación conserva el valor literal.

Probar TypedDict

from typing import TypedDict

class Usuario(TypedDict):
    id: int
    nombre: str

usuario: Usuario = {"id": 1, "nombre": "Ana"}
assert_type(usuario["id"], int)
assert_type(usuario["nombre"], str)

Las claves opcionales deben comprobarse antes del acceso. reveal_type ayuda antes y después de in.

Probar TypeGuard y TypeIs

from typing import TypeGuard

def es_str(valor: object) -> TypeGuard[str]:
    return isinstance(valor, str)

item: object = "x"
if es_str(item):
    assert_type(item, str)

La prueba confirma el refinamiento verdadero. Para TypeIs, prueba también la rama falsa. Consulta TypeGuard en Python.

Probar Protocol

from typing import Protocol

class Cerrable(Protocol):
    def cerrar(self) -> None: ...

class Archivo:
    def cerrar(self) -> None: ...

archivo = Archivo()
assert_type(archivo, Archivo)

cerrable: Cerrable = archivo
assert_type(cerrable, Cerrable)

assert_type comprueba el tipo estático de la variable, no solo compatibilidad estructural.

Decoradores y pérdida de firma

@mi_decorador
def buscar(id_: int) -> str:
    ...

reveal_type(buscar)
assert_type(buscar(1), str)

Decoradores mal tipados convierten funciones precisas en Callable[..., Any]. ParamSpec puede preservar el contrato. Consulta ParamSpec en Python.

Archivos de pruebas estáticas

Crea archivos como tests/typing/test_api.py. No necesitan ejecutarse con pytest; el CI ejecuta el analizador sobre ellos. Documentan la experiencia esperada del consumidor.

Pruebas positivas y negativas

assert_type expresa inferencia correcta. Las llamadas que deben fallar requieren comentarios o herramientas específicas del analizador. Mantén los casos negativos cerca de la API protegida.

No dependas del texto del diagnóstico

Los mensajes de reveal_type cambian entre analizadores. Usa assert_type para expectativas automatizadas y reveal_type para exploración.

Tipos equivalentes

Sintaxis distintas pueden representar el mismo tipo y el orden de uniones puede variar. El analizador decide equivalencia sin comparar strings.

Any puede ocultar problemas

Si una dependencia devuelve Any, muchas operaciones pasan sin verificar. Añade pruebas en las fronteras y configura reglas estrictas. reveal_type muestra rápidamente dónde entró Any.

Never y ramas inalcanzables

En código exhaustivo, reveal_type puede mostrar Never. La guía de Never en Python explica assert_never().

Self y métodos fluidos

builder = BuilderEspecial().configurar()
assert_type(builder, BuilderEspecial)

La prueba garantiza que un método con Self conserva subclases.

Tipos variádicos

resultado = agregar_prefijo((1, "a"))
assert_type(resultado, tuple[str, int, str])

TypeVarTuple y Unpack pueden producir inferencias complejas. Las aserciones documentan la relación posicional.

Comportamiento de runtime

assert_type(valor, Tipo) devuelve valor sin comprobarlo. reveal_type tampoco sustituye validación. No uses estas funciones para proteger entradas de usuario.

Eliminar reveals exploratorios

reveal_type es útil durante desarrollo, pero puede generar salida o ensuciar el código. Mantenlo en pruebas dedicadas o elimínalo después del diagnóstico.

Compatibilidad

Usa typing_extensions.assert_type cuando sea necesario. El comportamiento estático depende mucho de la versión del analizador. Fija versiones en CI y revisa actualizaciones.

Comparar analizadores

Mypy y pyright pueden inferir casos complejos de forma diferente. Si la biblioteca soporta ambos, ejecuta la misma suite con los dos y evita depender de comportamientos no especificados.

Errores comunes

  • Esperar validación de runtime: assert_type no llama isinstance.
  • Dejar reveal_type en producción: puede producir salida innecesaria.
  • Probar solo internos: prueba la API del consumidor.
  • Permitir que Any se propague: las aserciones pierden valor.
  • Comparar strings de diagnóstico: el texto cambia.
  • No fijar el analizador: las actualizaciones alteran inferencia.

Ejemplo completo: API de caché

from typing import TypeVar, overload, assert_type

T = TypeVar("T")
_AUSENTE = object()

@overload
def obtener(clave: str) -> object: ...
@overload
def obtener(clave: str, default: T) -> object | T: ...

def obtener(clave: str, default: object = _AUSENTE) -> object:
    ...

assert_type(obtener("x"), object)
assert_type(obtener("x", 0), object | int)
assert_type(obtener("x", None), object | None)

Las pruebas documentan la relación entre default y retorno. El CI informa cuando overloads o stubs cambian.

Estrategia para bibliotecas

Crea archivos de consumidores reales. Importa el paquete instalado. Prueba retornos, errores esperados, subclases, overloads, genéricos y stubs. El tipado público puede romperse aunque los tests de runtime sigan verdes.

Conclusión

reveal_type() permite investigar la inferencia. assert_type() convierte una expectativa en una prueba de regresión. Juntos hacen las APIs tipadas más predecibles.

La documentación oficial de assert_type y reveal_type en Python define su comportamiento. Usa reveal_type para explorar, assert_type para automatizar y ejecuta las pruebas con las configuraciones exactas soportadas por el proyecto.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    A person typing on a laptop with a Python programming book visible, capturing technology and learning.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    get_type_hints en Python: lee anotaciones

    Aprende get_type_hints en Python para resolver referencias futuras, conservar Annotated e inspeccionar funciones y clases con seguridad.

    Ler mais

    Tempo de leitura: 5 minutos
    29/08/2026
    A developer typing code on a laptop with a Python book beside in an office.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    runtime_checkable en Python: Protocol runtime

    Aprende runtime_checkable en Python para comprobar Protocol con isinstance, entender límites y diseñar contratos estructurales seguros.

    Ler mais

    Tempo de leitura: 5 minutos
    29/08/2026
    Close-up of a laptop screen with code and a coffee mug, perfect for tech abstract themes.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    Unpack en Python: kwargs y tipos variádicos

    Aprende typing.Unpack en Python para tipar **kwargs con TypedDict, expandir tuplas variádicas y conservar firmas precisas.

    Ler mais

    Tempo de leitura: 4 minutos
    29/08/2026
    Person holding Python logo sticker with blurred background, highlighting programming focus.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    Required y NotRequired: campos opcionales en TypedDict

    Aprende Required y NotRequired en Python para controlar claves obligatorias y opcionales de TypedDict sin confundir ausencia con None.

    Ler mais

    Tempo de leitura: 5 minutos
    29/08/2026
    Ball python slithering on a sunlit gravel pathway outdoors.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    ReadOnly en Python: protege campos TypedDict

    Aprende ReadOnly en Python para proteger campos TypedDict, modelar contratos estables y evitar escrituras accidentales.

    Ler mais

    Tempo de leitura: 5 minutos
    29/08/2026
    Close-up view of a computer screen displaying code in a software development environment.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    TypeAliasType en Python: alias en runtime

    Aprende TypeAliasType en Python para crear alias explícitos, inspeccionarlos en runtime y modelar APIs genéricas reutilizables.

    Ler mais

    Tempo de leitura: 6 minutos
    29/08/2026