Python posee palabras que forman parte de la gramática del lenguaje y no pueden utilizarse libremente como nombres de variables, funciones o clases. El módulo keyword en Python permite consultar esas palabras directamente desde el intérprete activo, distinguir keywords estrictas de soft keywords y validar nombres antes de generar código, crear modelos o transformar archivos fuente.
Esta guía explica iskeyword(), kwlist, issoftkeyword() y softkwlist, además de identificadores Unicode, generación de código y compatibilidad entre versiones. Complementa nuestros artículos sobre tokenize en Python, codeop, symtable, bytecode con dis y py_compile.
Qué resuelve el módulo keyword
Una aplicación puede recibir nombres de columnas, campos JSON, parámetros, plantillas o definiciones creadas por usuarios. Algunos textos son identificadores válidos; otros contienen espacios, comienzan con números o coinciden con palabras reservadas como class, return y for.
El módulo keyword responde específicamente si una cadena pertenece al conjunto de palabras de la gramática del intérprete. No reemplaza todas las reglas de identificadores, pero cubre una parte esencial de la validación.
import keyword
print(keyword.iskeyword("class")) # True
print(keyword.iskeyword("cliente")) # FalsePalabras reservadas estrictas
Una keyword estricta tiene significado sintáctico permanente en los contextos definidos por el lenguaje. No puede utilizarse directamente como identificador.
class = "curso" # SyntaxErrorLa documentación oficial de keyword indica que iskeyword() consulta las palabras definidas por la versión del intérprete en ejecución.
Usar iskeyword()
keyword.iskeyword(texto) devuelve True cuando la cadena es una palabra reservada estricta.
import keyword
candidatos = ["nombre", "for", "async", "resultado"]
for candidato in candidatos:
if keyword.iskeyword(candidato):
print(candidato, "es una keyword")La función es útil en generadores de clases, APIs de plantillas, migradores y herramientas que convierten esquemas externos en código Python.
Consultar kwlist
keyword.kwlist contiene todas las keywords estrictas conocidas por el intérprete.
import keyword
for palabra in keyword.kwlist:
print(palabra)No copies una lista fija desde un tutorial. El conjunto puede evolucionar entre versiones. Consultar kwlist mantiene la herramienta alineada con el runtime real.
Soft keywords
Una soft keyword solo actúa como palabra especial en determinados contextos gramaticales. Fuera de ellos, puede seguir siendo un identificador válido.
Por ejemplo, versiones modernas de Python utilizan palabras contextuales en pattern matching y en otras construcciones del lenguaje. Su tratamiento depende de dónde aparecen, no únicamente del texto.
match = "texto permitido fuera del contexto especial"
print(match)Por eso, no debes bloquear automáticamente toda soft keyword como si fuera una keyword estricta.
Usar issoftkeyword()
keyword.issoftkeyword() informa si una cadena pertenece al conjunto de palabras contextuales del intérprete.
import keyword
for nombre in ["match", "case", "type", "cliente"]:
print(nombre, keyword.issoftkeyword(nombre))La función fue añadida para que analizadores y generadores puedan seguir la gramática sin mantener listas manuales.
Consultar softkwlist
keyword.softkwlist expone la lista actual de soft keywords.
import keyword
print(keyword.softkwlist)La presencia de una palabra en esta lista no significa que siempre sea inválida como nombre. Significa que una herramienta que produce código debe analizar el contexto donde la insertará.
Validar un identificador completo
iskeyword() solo comprueba palabras reservadas. Para verificar la forma léxica del identificador, combínalo con str.isidentifier().
import keyword
def identificador_valido(nombre):
return nombre.isidentifier() and not keyword.iskeyword(nombre)
for nombre in ["cliente", "2clientes", "class", "total_anual"]:
print(nombre, identificador_valido(nombre))isidentifier() aplica las reglas Unicode del intérprete. Así acepta letras de muchos alfabetos y rechaza espacios, guiones y nombres que comienzan con dígitos.
Identificadores Unicode
Python permite identificadores Unicode válidos.
nombres = ["año", "привет", "Δvalor", "valor-total"]
for nombre in nombres:
print(nombre, nombre.isidentifier())La validez sintáctica no garantiza que el nombre sea apropiado para una base de código. Los equipos pueden aplicar reglas adicionales de estilo, normalización y seguridad.
Normalización y caracteres confusos
Dos cadenas visualmente parecidas pueden utilizar caracteres Unicode diferentes. Una herramienta que acepta nombres externos debe considerar normalización y caracteres homógrafos.
import unicodedata
nombre = unicodedata.normalize("NFKC", nombre_recibido)La gramática de Python aplica reglas de normalización a identificadores. Aun así, interfaces públicas deben registrar el valor original y detectar casos engañosos según su modelo de amenazas.
Convertir nombres inválidos
Un generador puede transformar nombres externos en identificadores seguros.
import keyword
import re
import unicodedata
def convertir_identificador(texto):
texto = unicodedata.normalize("NFKC", texto).strip()
texto = re.sub(r"\W+", "_", texto, flags=re.UNICODE)
texto = texto.strip("_") or "campo"
if texto[0].isdigit():
texto = "campo_" + texto
if keyword.iskeyword(texto):
texto += "_"
return textoLa transformación debe manejar colisiones. Por ejemplo, class y class_ pueden terminar con el mismo resultado.
Resolver colisiones
def nombre_unico(base, usados):
candidato = base
numero = 2
while candidato in usados:
candidato = f"{base}_{numero}"
numero += 1
usados.add(candidato)
return candidatoGuarda también un mapa entre el nombre original y el identificador generado. Así puedes serializar datos sin perder la clave externa.
Generación de clases
Al convertir un esquema en atributos de clase, valida cada nombre antes de construir el código.
campos = ["nombre", "class", "fecha-creacion"]
seguros = [convertir_identificador(campo) for campo in campos]
print(seguros)Para estructuras sencillas, APIs como dataclasses.make_dataclass(), NamedTuple y types.new_class() son preferibles a concatenar texto y llamar exec().
Generación de funciones
Los nombres de parámetros también deben ser identificadores no reservados.
def validar_parametros(parametros):
invalidos = [
nombre
for nombre in parametros
if not nombre.isidentifier() or keyword.iskeyword(nombre)
]
if invalidos:
raise ValueError(f"Parámetros inválidos: {invalidos}")Además, comprueba duplicados y restricciones de la firma, como parámetros posicionales y keywords-only.
No confundir keywords con built-ins
Nombres como list, str, open y id no son keywords. Python permite utilizarlos como variables, aunque eso oculta temporalmente el built-in.
list = [1, 2, 3]
# list("abc") deja de llamar al tipo built-in en este ámbitoSi necesitas evitar built-ins, consulta el módulo builtins o utiliza un linter. Esa es una política distinta de la validación gramatical.
Keywords y atributos
La sintaxis normal tampoco permite escribir una keyword después del punto.
# objeto.class # SyntaxErrorSin embargo, un objeto puede contener esa clave en un mapping o incluso un atributo accesible mediante getattr().
valor = getattr(objeto, "class", None)Eso no significa que el nombre sea conveniente. Las APIs deben proporcionar aliases legibles cuando trabajan con datos externos.
Keywords en diccionarios y JSON
Las claves de diccionario son datos y pueden contener cualquier cadena.
datos = {
"class": "premium",
"for": "auditoría",
}El problema aparece únicamente al transformar esas claves en identificadores o argumentos nombrados.
Compatibilidad entre versiones
Un nombre aceptado hoy puede adquirir un papel especial en una versión futura. Herramientas que generan código para otro runtime deben validar contra la versión objetivo, no necesariamente contra la versión que ejecuta el generador.
Una estrategia segura es ejecutar la validación dentro de cada versión soportada durante CI. Contenedores y matrices de pruebas ayudan a comprobar kwlist, softkwlist y compilación real.
Validar con compile()
Después de construir un fragmento, usa compile() para verificar la sintaxis sin ejecutarlo.
codigo = "def procesar(valor):\n return valor\n"
compile(codigo, "", "exec") Compilar no convierte código desconocido en seguro. Solo confirma que la sintaxis es válida.
Combinar con tokenize
keyword clasifica cadenas aisladas. Para analizar un archivo completo, tokenize preserva posiciones, comentarios y tokens.
Un refactorizador puede recorrer tokens de tipo NAME, consultar iskeyword() y considerar el contexto de soft keywords. No hagas reemplazos globales de texto, porque podrías alterar strings y comentarios.
Combinar con ast
Para comprender la estructura sintáctica, utiliza ast.parse(). El parser ya interpreta keywords y soft keywords según el contexto.
import ast
arbol = ast.parse(codigo_fuente)
print(ast.dump(arbol, indent=2))keyword es ideal para validación previa; ast es mejor para decisiones estructurales.
Herramientas de plantillas
Una plantilla que produce módulos debe validar todos los nombres antes de renderizar.
def contexto_seguro(campos):
usados = set()
resultado = {}
for original in campos:
base = convertir_identificador(original)
resultado[original] = nombre_unico(base, usados)
return resultadoEscapa también valores literales con repr() o formatos estructurados en lugar de concatenarlos directamente.
Linters y editores
Linters usan información más amplia que keyword: alcance, built-ins, estilo, variables no utilizadas y compatibilidad de versión. El módulo sigue siendo útil como bloque básico y fuente oficial del conjunto vigente.
Tests recomendados
Prueba palabras estrictas, soft keywords, Unicode, espacios, guiones, dígitos iniciales y colisiones.
def test_identificadores():
assert identificador_valido("cliente")
assert identificador_valido("año")
assert not identificador_valido("class")
assert not identificador_valido("2clientes")
assert not identificador_valido("valor-total")Ejecuta los tests en todas las versiones de Python declaradas como compatibles.
Seguridad
Un identificador válido no vuelve confiable el código generado. La entrada puede influir en expresiones, imports, bases de clases o valores ejecutables.
Evita eval() y exec() con entrada externa. Prefiere mapas de operaciones permitidas, parsers estructurados y procesos aislados cuando realmente necesitas ejecutar código de terceros.
Errores frecuentes
- Mantener una lista manual de keywords.
- Usar solo
iskeyword()y olvidarisidentifier(). - Bloquear soft keywords en todos los contextos.
- Confundir built-ins con palabras reservadas.
- Ignorar Unicode y normalización.
- No resolver colisiones después de transformar nombres.
- Validar contra una versión diferente de la versión objetivo.
- Suponer que sintaxis válida significa código seguro.
Buenas prácticas
- Consulta las listas del intérprete en ejecución.
- Combina
isidentifier()coniskeyword(). - Trata soft keywords según el contexto.
- Conserva el nombre externo original.
- Define una política determinista de aliases.
- Prueba todas las versiones soportadas.
- Compila el código generado antes de distribuirlo.
- No ejecutes entrada no confiable.
Conclusión
El módulo keyword en Python ofrece una fuente pequeña y confiable para saber qué palabras pertenecen a la gramática del intérprete. iskeyword() y kwlist cubren palabras estrictas, mientras issoftkeyword() y softkwlist ayudan con construcciones contextuales.
Combinado con str.isidentifier(), normalización Unicode, resolución de colisiones y pruebas entre versiones, el módulo permite crear generadores y analizadores más robustos. Su responsabilidad es validar nombres; la seguridad del código generado requiere controles adicionales.





