Geradores de código, validadores de formulários, ferramentas de refatoração e sistemas que transformam nomes externos em identificadores Python precisam saber se uma palavra pode ser usada como variável, atributo, função ou classe. O módulo keyword no Python expõe as palavras reservadas reconhecidas pelo interpretador atual e também as chamadas soft keywords, que possuem significado especial somente em contextos específicos.
Neste guia, você aprenderá a usar iskeyword(), kwlist, issoftkeyword() e softkwlist, além de criar validadores compatíveis com várias versões. O conteúdo complementa nossos artigos sobre tokenize, symtable, codeop, AST no Python e types.
O que é uma palavra reservada
Palavras reservadas participam da gramática da linguagem e não podem ser usadas como identificadores comuns.
class = "relatorio" # SyntaxError
return = 10 # SyntaxErrorExemplos conhecidos incluem class, def, return, if, for, while, try, import e lambda. A lista depende da versão do Python e não deve ser copiada manualmente para uma ferramenta duradoura.
Verificar com iskeyword()
keyword.iskeyword() informa se uma string é uma palavra reservada do interpretador atual.
import keyword
print(keyword.iskeyword("class")) # True
print(keyword.iskeyword("cliente")) # FalseA função aceita uma string e devolve booleano. Ela não verifica todas as regras de identificadores; apenas palavras reservadas.
Consultar kwlist
keyword.kwlist contém as palavras reservadas em ordem alfabética.
import keyword
for palavra in keyword.kwlist:
print(palavra)A lista é útil para interfaces educativas, syntax highlighting, testes e geração de nomes alternativos.
Não altere kwlist
Embora o objeto exposto seja uma lista, modificá-lo não muda a gramática do Python e pode quebrar o próprio código que consulta o módulo.
# Não faça isso
keyword.kwlist.append("cliente")Trate a lista como informação somente leitura. Faça uma cópia ou converta para frozenset quando precisar de uma coleção própria.
RESERVADAS = frozenset(keyword.kwlist)O que são soft keywords
Soft keywords são palavras que recebem significado especial apenas em determinados contextos gramaticais. Fora desses contextos, ainda podem funcionar como identificadores.
Esse mecanismo permite evoluir a linguagem com menos quebra de código existente. Em versões modernas, estruturas como pattern matching e declarações de tipos utilizam palavras contextuais.
Verificar soft keywords
keyword.issoftkeyword() verifica se uma string pertence à lista contextual do interpretador.
print(keyword.issoftkeyword("match"))
print(keyword.issoftkeyword("case"))
print(keyword.issoftkeyword("cliente"))A documentação oficial de keyword recomenda consultar o módulo em vez de manter listas fixas, pois a gramática pode evoluir.
Consultar softkwlist
for palavra in keyword.softkwlist:
print(palavra)Nem toda soft keyword precisa ser rejeitada como nome. A decisão depende de onde o identificador será inserido.
Soft keyword pode ser identificador
Uma palavra contextual pode ser válida em várias posições.
match = "texto"
case = 10
print(match, case)Porém, em uma construção de pattern matching, as mesmas palavras participam da sintaxe.
match valor:
case 0:
print("zero")Uma ferramenta de geração de código deve considerar o contexto completo, não apenas bloquear todas as soft keywords.
Validar um identificador completo
Para verificar se uma string pode ser um identificador simples, combine str.isidentifier() com iskeyword().
def identificador_valido(nome: str) -> bool:
return nome.isidentifier() and not keyword.iskeyword(nome)
print(identificador_valido("cliente_id"))
print(identificador_valido("2clientes"))
print(identificador_valido("class"))isidentifier() considera regras Unicode da versão atual. Ele não informa se o nome é apropriado, legível ou permitido pela política do projeto.
Nomes Unicode
Python aceita muitos caracteres Unicode em identificadores.
print("ação".isidentifier())
print("π".isidentifier())A referência oficial de análise lexical descreve normalização e categorias permitidas. Em APIs públicas, nomes ASCII podem ser preferíveis por interoperabilidade, mas isso é uma política do projeto, não uma exigência da linguagem.
Gerar um nome seguro
Uma ferramenta pode normalizar um nome externo e acrescentar sufixo quando ele coincide com uma keyword.
import re
import unicodedata
def criar_identificador(texto: str) -> str:
texto = unicodedata.normalize("NFKC", texto).strip()
texto = re.sub(r"\W+", "_", texto, flags=re.UNICODE)
texto = texto.strip("_") or "valor"
if texto[0].isdigit():
texto = "_" + texto
if keyword.iskeyword(texto):
texto += "_"
if not texto.isidentifier():
raise ValueError("não foi possível criar identificador")
return textoNão use essa transformação para decisões de segurança ou autorização. Nomes visualmente parecidos podem usar caracteres Unicode diferentes.
Convenção do underscore
Acrescentar underscore é uma convenção comum para escapar de palavras reservadas.
class_ = "Relatorio"
from_ = "origem"
async_ = FalseEvite abreviações obscuras. Quando o nome vem de um campo externo, mantenha um mapa entre o nome original e o identificador Python.
Validar nomes de atributos
Palavras reservadas podem ser usadas como chaves de dicionário e, com APIs dinâmicas, até como nomes de atributos armazenados.
objeto.__dict__["class"] = "especial"
print(getattr(objeto, "class"))Entretanto, objeto.class não é sintaxe válida. Geradores de código devem rejeitar ou transformar esses nomes mesmo quando setattr() os aceita.
Campos de JSON e banco de dados
Dados externos frequentemente possuem campos como class, from ou global. Não altere o esquema externo silenciosamente.
MAPA = {
"class": "class_",
"from": "from_",
}
valor = payload["class"]
modelo.class_ = valorSerialização de volta deve restaurar o nome original.
Geração de funções
Antes de inserir parâmetros em código-fonte gerado, valide cada nome.
def assinatura_segura(nomes):
for nome in nomes:
if not identificador_valido(nome):
raise ValueError(f"parâmetro inválido: {nome!r}")
return ", ".join(nomes)Mesmo com nomes válidos, concatenar código e executar exec() continua perigoso quando outras partes vêm de usuários. Prefira estruturas de dados, closures ou AST construído com regras restritas.
Keywords em templates
Um template que gera classes, dataclasses ou APIs deve testar nomes de classe, atributos, parâmetros e métodos separadamente.
O fato de um nome ser válido como atributo via getattr() não garante que possa aparecer após ponto em código. Compile uma amostra em testes para detectar regras contextuais.
Compatibilidade entre versões
Uma palavra pode tornar-se reservada ou contextual em uma versão futura. Ferramentas que geram código destinado a outro runtime não devem consultar apenas o Python em que estão rodando.
Opções possíveis:
- executar a validação no interpretador de destino;
- manter tabelas versionadas obtidas de fontes oficiais;
- compilar o código com todas as versões suportadas;
- usar containers ou CI com uma matriz de Python.
Não reutilizar lista de uma versão
Salvar keyword.kwlist de um Python antigo e aplicá-la para sempre pode permitir sintaxe inválida em versões novas ou rejeitar nomes que deixaram de ser especiais.
Registre a versão do interpretador junto aos artefatos gerados e teste a versão mínima e máxima suportadas.
Syntax highlighting
Editores podem usar kwlist para palavras rígidas e softkwlist para realce contextual. Apenas colorir todas as soft keywords como reservadas em qualquer posição gera falsos positivos.
Um highlighter preciso precisa de tokenizer ou parser. O módulo keyword fornece a classificação, não a posição gramatical.
Integração com tokenize
tokenize normalmente classifica identificadores e keywords como tokens NAME. A distinção final depende do parser.
import io
import tokenize
codigo = b"if valor: pass\n"
for token in tokenize.tokenize(io.BytesIO(codigo).readline):
if token.type == tokenize.NAME:
print(token.string, keyword.iskeyword(token.string))Isso é útil em analisadores leves, mas soft keywords exigem contexto adicional.
Integração com AST
O parser já aplica as regras da versão atual. Compilar ou usar ast.parse() é a confirmação mais forte de que um trecho completo possui sintaxe válida.
import ast
try:
ast.parse("cliente = 1")
except SyntaxError as erro:
print(erro)Não execute o código para validá-lo; parsing é suficiente para sintaxe.
Ferramentas de refatoração
Ao renomear símbolos, verifique:
- se o novo nome é identificador;
- se não é keyword rígida;
- se não cria conflito no escopo;
- se soft keywords são válidas naquele contexto;
- se referências em strings e configurações também precisam mudar.
symtable e AST ajudam a analisar escopos e usos.
Validação em APIs
Se uma API recebe o nome de um campo que será convertido em atributo Python, retorne uma mensagem clara.
def validar_campo(nome):
if not nome.isidentifier():
raise ValueError("o campo não é um identificador Python")
if keyword.iskeyword(nome):
raise ValueError(f"{nome!r} é palavra reservada")Você pode oferecer automaticamente uma alternativa, mas mostre o mapeamento ao usuário.
Desempenho
Consultas são rápidas, mas uma ferramenta que valida milhões de nomes pode converter as listas em conjuntos próprios.
KEYWORDS = frozenset(keyword.kwlist)
SOFT_KEYWORDS = frozenset(keyword.softkwlist)Não modifique as coleções globais do módulo e reconstrua os conjuntos quando mudar de interpretador.
Testes
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("cliente-id")Inclua todas as keywords atuais, soft keywords em diferentes contextos, Unicode, strings vazias e nomes próximos a built-ins como list e str.
Built-ins não são keywords
Nomes como list, dict, str, id e input não são reservados.
print(keyword.iskeyword("list")) # FalseAtribuir a esses nomes é permitido, mas pode esconder built-ins e confundir o código.
list = [1, 2, 3]
# list("abc") agora falhaLinters ajudam a aplicar essa política adicional.
Erros frequentes
- Validar apenas com
iskeyword(). - Bloquear toda soft keyword em qualquer contexto.
- Manter uma lista manual desatualizada.
- Presumir que
setattr()garante sintaxe com ponto. - Confundir built-ins com palavras reservadas.
- Gerar código para outra versão sem testar.
- Modificar
kwlistousoftkwlist. - Executar código apenas para validar sintaxe.
Boas práticas
- Combine
isidentifier()eiskeyword(). - Considere soft keywords conforme o contexto.
- Consulte a versão real do interpretador alvo.
- Mantenha mapas para nomes externos transformados.
- Use AST ou compilação para validar trechos completos.
- Teste todas as versões suportadas.
- Aplique lint para built-ins sobrescritos.
- Trate Unicode e normalização conscientemente.
Conclusão
O módulo keyword no Python fornece a lista oficial de palavras reservadas e palavras-chave contextuais do interpretador atual. iskeyword() e issoftkeyword() ajudam validadores, geradores de código, editores e refatoradores a acompanhar a evolução da linguagem.
A validação correta vai além de uma lista: nomes precisam satisfazer isidentifier(), soft keywords dependem do contexto e código destinado a outra versão precisa ser testado naquele runtime. Com essas camadas, ferramentas podem produzir identificadores legíveis sem gerar sintaxe inválida.





