token en Python: constantes del parser

Publicado el: 07/08/2026
Tempo de leitura: 7 minutos
Código fuente que representa tokens y constantes del parser con el módulo token en Python

Las herramientas que inspeccionan código fuente necesitan distinguir identificadores, números, strings, comentarios, operadores, indentación y marcadores de fin de entrada. El módulo token en Python proporciona las constantes numéricas y los mapas utilizados para representar esos elementos léxicos en tokenizers, parsers, depuradores, linters y transformadores de código.

Esta guía explica tok_name, EXACT_TOKEN_TYPES, ISTERMINAL(), ISNONTERMINAL() e ISEOF(), además de NAME, NUMBER, STRING, OP, indentación, f-strings y template strings. Complementa nuestros artículos sobre tokenize en Python, keyword, symtable, bytecode con dis y codeop.

Qué ofrece el módulo token

El archivo token.py asigna nombres simbólicos a categorías de tokens. Los valores numéricos son detalles de implementación y pueden cambiar entre versiones de Python. Por eso, una aplicación debe comparar con token.NAME y no con un entero copiado de otra ejecución.

import token

print(token.NAME)
print(token.NUMBER)
print(token.STRING)
print(token.tok_name[token.NAME])

La documentación oficial de token explica que estas constantes representan nodos terminales de la gramática y reflejan definiciones utilizadas por el parser.

token y tokenize cumplen funciones diferentes

El módulo token define constantes y mappings. El módulo tokenize lee bytes o texto y produce registros con tipo, texto original, posición inicial, posición final y línea fuente.

import io
import token
import tokenize

codigo = b"total = precio + impuesto\n"

for elemento in tokenize.tokenize(io.BytesIO(codigo).readline):
    nombre = token.tok_name.get(elemento.type, str(elemento.type))
    print(nombre, elemento.string)

Token es el vocabulario; tokenize es el scanner que genera elementos de ese vocabulario.

Usar tok_name

token.tok_name convierte códigos numéricos en nombres legibles.

for codigo, nombre in sorted(token.tok_name.items()):
    print(codigo, nombre)

Este mapping mejora logs, visualizadores y mensajes de error. Mostrar INDENT o DOUBLESTAR es mucho más útil que presentar únicamente un número.

El token NAME

NAME representa identificadores y palabras cuyo papel final depende del parser.

codigo = b"for item in items:\n    print(item)\n"

Según la API y las opciones del tokenizer, textos como for, item, in y print pueden aparecer inicialmente como nombres. Combina el texto con el módulo keyword para reconocer palabras reservadas y contextuales.

import keyword

if elemento.type == token.NAME:
    if keyword.iskeyword(elemento.string):
        categoria = "keyword"
    elif keyword.issoftkeyword(elemento.string):
        categoria = "soft keyword"
    else:
        categoria = "identificador"

NUMBER conserva el texto original

NUMBER representa literales enteros, flotantes, complejos y números escritos en bases alternativas.

valores = b"10 3.14 0xff 1_000 2j\n"

El token conserva el lexema. No convierte hexadecimal a entero ni elimina underscores. Deja la interpretación al parser o utiliza una conversión segura diseñada para el formato.

STRING

STRING representa strings y bytes convencionales. El texto incluye prefijos, comillas y escapes sin evaluarlos.

codigo = b"ruta = r'C:\\temp'\n"

Esto permite que un formateador conserve el estilo de comillas. Cuando un literal confiable necesita convertirse, ast.literal_eval() es preferible a eval().

COMMENT

COMMENT identifica comentarios en la API pública de tokenize.

# comentario de configuración
limite = 10  # valor máximo

El parser ignora comentarios, pero formateadores, herramientas de documentación y refactorizadores deben preservarlos. Una AST por sí sola no conserva toda esta información.

NEWLINE y NL

NEWLINE termina una instrucción lógica. NL representa una ruptura física que no finaliza la expresión, por ejemplo dentro de paréntesis.

resultado = (
    primero
    + segundo
)

Las líneas internas generan NL; el cierre de la expresión produce NEWLINE. Esta diferencia ayuda a compiladores interactivos y formateadores.

INDENT y DEDENT

Python modela bloques mediante indentación. INDENT inicia un nivel más profundo y DEDENT regresa a un nivel exterior.

if activo:
    ejecutar()
    registrar()
finalizar()

El token de indentación incluye los espacios o tabs originales. Los analizadores de estilo pueden inspeccionarlo, mientras la validación de ambigüedad pertenece al tokenizer y a herramientas como tabnanny.

ENCODING

tokenize.tokenize() lee bytes y comienza siempre con un token ENCODING.

with open("modulo.py", "rb") as archivo:
    tokens = list(tokenize.tokenize(archivo.readline))

assert tokens[0].type == token.ENCODING

Python detecta la codificación mediante BOM o una declaración en las primeras líneas. La API basada en strings generate_tokens() no produce este marcador.

ENDMARKER

ENDMARKER señala el final de la entrada.

ultimo = tokens[-1]
assert ultimo.type == token.ENDMARKER

Los consumidores de streams deben procesarlo para cerrar estado pendiente y confirmar que toda la entrada fue leída.

OP y tipos exactos

El módulo tokenize suele reportar operadores y delimitadores mediante la categoría genérica OP.

codigo = b"resultado += valor ** 2\n"

Consulta TokenInfo.exact_type para distinguir +=, **, paréntesis, comas y otros símbolos.

for elemento in tokenize.tokenize(io.BytesIO(codigo).readline):
    if elemento.type == token.OP:
        print(elemento.string, token.tok_name[elemento.exact_type])

El token genérico puede refinarse como PLUSEQUAL, DOUBLESTAR, LPAR u otra constante específica.

EXACT_TOKEN_TYPES

token.EXACT_TOKEN_TYPES mapea el texto del símbolo a su código exacto.

assert token.EXACT_TOKEN_TYPES["+"] == token.PLUS
assert token.EXACT_TOKEN_TYPES[":="] == token.COLONEQUAL
assert token.EXACT_TOKEN_TYPES["->"] == token.RARROW

El mapping resulta útil cuando una herramienta ya tiene la representación textual del operador.

Los operadores evolucionan

El módulo incluye constantes para paréntesis, corchetes, llaves, comas, dos puntos, operadores aritméticos, comparaciones, asignaciones compuestas, flechas de anotación y otros símbolos.

No mantengas una copia manual. Las versiones pueden añadir y retirar tokens, como ocurrió con COLONEQUAL, EXCLAMATION y constantes históricas de async.

Tokens de f-strings

Las versiones actuales exponen FSTRING_START, FSTRING_MIDDLE y FSTRING_END.

mensaje = f"Hola, {usuario.nombre}!"

El inicio incluye el prefijo y la comilla de apertura. El texto literal se divide en partes intermedias, mientras las expresiones de sustitución usan tokens normales dentro de llaves.

Prueba cada versión soportada porque la gramática y tokenización de f-strings han evolucionado.

Template strings en Python 3.14

Python 3.14 añade TSTRING_START, TSTRING_MIDDLE y TSTRING_END para template string literals.

Un paquete compatible con versiones anteriores no debe importar estas constantes sin comprobación.

if hasattr(token, "TSTRING_START"):
    soporta_tstrings = True

La detección de capacidades evita errores al importar el módulo en runtimes antiguos.

SOFT_KEYWORD

Existe una constante SOFT_KEYWORD para usos internos, pero tokenize normalmente entrega una palabra contextual como NAME.

if elemento.type == token.NAME and keyword.issoftkeyword(elemento.string):
    print("soft keyword potencial")

Solo el contexto sintáctico decide si la palabra tiene función especial. Analiza una AST cuando necesites certeza estructural.

ERRORTOKEN y excepciones

ERRORTOKEN puede representar entrada incorrecta en algunos casos. Sin embargo, tokenize también puede lanzar TokenError o producir tokens que el parser rechazará después.

try:
    tokens = list(tokenize.generate_tokens(reader))
except tokenize.TokenError as error:
    print("entrada incompleta o inválida", error)

La ausencia de ERRORTOKEN no garantiza sintaxis válida. Usa compile() o ast.parse() después del análisis léxico.

TYPE_COMMENT y TYPE_IGNORE

TYPE_COMMENT y TYPE_IGNORE apoyan modos del compilador que reconocen comentarios de tipado.

resultado = cargar()  # type: Resultado
ignorar()             # type: ignore

El tokenizer público no produce estos tipos en todas las configuraciones. Las herramientas de tipado suelen solicitar opciones específicas de AST.

ISTERMINAL()

token.ISTERMINAL(valor) informa si el código representa un token terminal.

assert token.ISTERMINAL(token.NAME)

Esta función aparece principalmente en infraestructura que trabaja con gramáticas o árboles concretos del parser.

ISNONTERMINAL()

ISNONTERMINAL() verifica símbolos que representan reglas compuestas.

def clasificar(codigo):
    if token.ISTERMINAL(codigo):
        return "terminal"
    if token.ISNONTERMINAL(codigo):
        return "no terminal"
    return "desconocido"

La mayoría de herramientas modernas usa AST, pero los sistemas de parsing aún pueden necesitar esta distinción.

ISEOF()

ISEOF() identifica el marcador de fin de entrada sin comparar un número fijo.

assert token.ISEOF(token.ENDMARKER)

La función mantiene la intención clara y reduce acoplamiento con detalles internos.

N_TOKENS

N_TOKENS informa cuántos tipos define el intérprete actual.

print(token.N_TOKENS)

No lo utilices como formato persistente sin versión. La cantidad y los valores pueden cambiar.

Persistir nombres y versión

Cuando guardes resultados de análisis, registra el nombre simbólico y la versión del intérprete.

import platform

registro = {
    "python": platform.python_version(),
    "tipo": token.tok_name[elemento.type],
    "texto": elemento.string,
}

Un entero almacenado por una versión puede tener otro significado en una versión futura.

Formateadores y refactorizadores

Una transformación que debe preservar comentarios y espacios puede modificar tokens y reconstruir el código con tokenize.untokenize().

nuevos = []
for elemento in tokens:
    if elemento.type == token.NAME and elemento.string == "nombre_antiguo":
        elemento = elemento._replace(string="nombre_nuevo")
    nuevos.append(elemento)

resultado = tokenize.untokenize(nuevos)

Un renombrado correcto necesita análisis de scope. Combina tokens con symtable o AST para no modificar nombres sin relación.

Linters

Los linters pueden detectar operadores prohibidos o características concretas con exact_type.

if elemento.exact_type == token.COLONEQUAL:
    reportar_walrus(elemento.start)

Conserva posiciones y líneas originales para generar diagnósticos útiles.

Pruebas entre versiones

Ejecuta una matriz de CI con todos los runtimes soportados. Verifica constantes añadidas o eliminadas, f-strings, soft keywords y operadores exactos.

def test_potencia_exacta():
    assert token.EXACT_TOKEN_TYPES["**"] == token.DOUBLESTAR

La detección de recursos es más segura que importar un nombre inexistente.

Seguridad

Tokenizar no ejecuta el código, pero tampoco constituye una sandbox. Una entrada enorme o adversarial puede consumir recursos, y el código seguirá siendo peligroso si se ejecuta posteriormente.

Aplica límites de tamaño y tiempo. Nunca envíes entrada externa tokenizada directamente a eval() o exec().

Errores frecuentes

  • Comparar tipos con números literales.
  • Confundir token con tokenize.
  • Tratar todos los OP como un único operador.
  • Ignorar exact_type.
  • Confundir NL y NEWLINE.
  • Esperar soft keywords como SOFT_KEYWORD.
  • Persistir códigos sin versión.
  • Ejecutar código solo porque se tokenizó correctamente.

Buenas prácticas

  • Compara con constantes simbólicas.
  • Usa tok_name en logs.
  • Consulta exact_type para operadores.
  • Conserva posiciones y líneas originales.
  • Detecta características nuevas con seguridad.
  • Prueba todas las versiones soportadas.
  • Combina tokens con AST y tablas de símbolos.
  • Limita entradas no confiables.

Conclusión

El módulo token en Python define el vocabulario utilizado para clasificar elementos léxicos del código fuente. Ofrece constantes legibles para nombres, números, strings, operadores, indentación, f-strings, template strings y marcadores internos.

Combinado con tokenize, keyword, AST y análisis de símbolos, permite construir herramientas precisas sin depender de números inestables. Utiliza nombres simbólicos, considera la versión objetivo y no confundas análisis sintáctico con ejecución segura.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Código fuente que representa palabras reservadas y soft keywords en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    keyword en Python: palabras reservadas

    Aprende keyword en Python para validar identificadores, palabras reservadas y soft keywords según la versión del intérprete.

    Ler mais

    Tempo de leitura: 7 minutos
    07/08/2026
    Arquitectura de software que representa clases abstractas con abc en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    abc en Python: clases abstractas

    Aprende abc en Python para crear clases abstractas, métodos obligatorios, subclasses virtuales y contratos estables.

    Ler mais

    Tempo de leitura: 5 minutos
    06/08/2026
    Código y estructuras que representan tipos del runtime con el módulo types en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    types en Python: tipos del runtime

    Aprende types en Python para usar SimpleNamespace, MappingProxyType, tipos del runtime y creación dinámica de clases.

    Ler mais

    Tempo de leitura: 5 minutos
    06/08/2026
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    sched en Python: programa eventos

    Aprende sched en Python para programar eventos, controlar prioridades, cancelar tareas y crear recurrencia con reloj monotónico.

    Ler mais

    Tempo de leitura: 7 minutos
    05/08/2026
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    atexit en Python: ejecuta limpieza al salir

    Aprende atexit en Python para ejecutar limpieza al salir, controlar el orden LIFO y evitar problemas con threads, señales y

    Ler mais

    Tempo de leitura: 7 minutos
    05/08/2026
    Monitor con código binario que representa análisis de opcodes pickle con pickletools en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    pickletools en Python: analiza pickles

    Aprende pickletools en Python para desmontar pickles, analizar opcodes y optimizar flujos sin ejecutar datos no confiables.

    Ler mais

    Tempo de leitura: 6 minutos
    05/08/2026