token no Python: constantes do parser

Publicado em: 07/08/2026
Tempo de leitura: 8 minutos
Código-fonte representando tokens e constantes do parser com o módulo token no Python

Ferramentas que analisam código-fonte precisam distinguir identificadores, números, strings, comentários, operadores, indentação e fim de arquivo. O módulo token no Python fornece as constantes numéricas e os mapas usados para representar esses elementos léxicos em tokenizadores, parsers, depuradores e transformadores de código.

Neste guia, você aprenderá a usar tok_name, EXACT_TOKEN_TYPES, ISTERMINAL(), ISNONTERMINAL() e ISEOF(), além de compreender NAME, NUMBER, STRING, OP, INDENT, DEDENT, f-strings e template strings. O conteúdo complementa nossos artigos sobre tokenize no Python, keyword, symtable, bytecode com dis e codeop.

O papel do módulo token

O arquivo token.py oferece nomes estáveis para categorias de tokens, mas os valores numéricos associados a esses nomes podem mudar entre versões do Python. Por isso, uma ferramenta deve comparar com constantes como token.NAME, não com números copiados de uma execução específica.

import token

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

A documentação oficial de token ressalta que as constantes representam nós terminais da gramática e espelham definições internas do parser.

token e tokenize não são a mesma coisa

O módulo token define constantes e mapas. O módulo tokenize lê bytes ou texto e produz uma sequência de tokens com tipo, conteúdo, posição inicial, posição final e linha original.

import io
import token
import tokenize

codigo = b"total = preco + imposto\n"

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

Em outras palavras, token é o vocabulário; tokenize é um scanner que utiliza esse vocabulário.

Usar tok_name

token.tok_name é um dicionário que converte o código numérico para um nome legível.

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

Esse mapa é essencial para logs, relatórios e ferramentas visuais. Exibir NAME é muito mais informativo que mostrar apenas um inteiro.

O token NAME

NAME representa identificadores e palavras que ainda precisam ser interpretadas pelo parser.

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

Textos como for, item, in, itens e print podem aparecer inicialmente como nomes dependendo da API e das opções. Para saber se uma string é keyword ou soft keyword, combine o valor textual com o módulo keyword.

import keyword

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

NUMBER

NUMBER representa literais numéricos como inteiros, floats, complexos e números escritos em bases diferentes.

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

O token preserva o texto original. Ele não converte automaticamente 0xff para inteiro nem remove underscores. Para interpretar o valor, use o parser ou uma função segura adequada ao formato.

STRING

STRING representa strings e bytes comuns. O texto inclui prefixo, aspas e escapes sem processá-los.

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

Uma ferramenta de estilo pode preservar a escolha de aspas porque recebe o lexema original. Para obter o valor real de um literal confiável, ast.literal_eval() é mais apropriado que eval().

COMMENT

COMMENT identifica comentários quando a sequência vem de tokenize.

# comentário de configuração
limite = 10  # valor máximo

O parser normalmente ignora comentários, mas formatadores, linters e refatoradores precisam preservá-los. Essa é uma das razões para usar tokenize em vez de trabalhar apenas com AST.

NEWLINE e NL

NEWLINE encerra uma linha lógica. NL representa uma quebra física que não encerra a instrução, por exemplo dentro de parênteses.

resultado = (
    primeiro
    + segundo
)

As quebras internas produzem NL; o fim da expressão produz NEWLINE. Essa distinção ajuda formatadores a preservar layout e detectores de entrada interativa a saber se um comando terminou.

INDENT e DEDENT

Python representa blocos por indentação. INDENT marca a entrada em um bloco, enquanto DEDENT marca a saída.

if ativo:
    executar()
    registrar()
finalizar()

O token INDENT contém o prefixo de espaços ou tabs. Um analisador pode comparar estilos, mas deve deixar a validação de ambiguidade para o tokenizer e ferramentas como tabnanny.

ENCODING

tokenize.tokenize() trabalha com bytes e começa a sequência com ENCODING.

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

print(tokens[0].type == token.ENCODING)

A codificação é detectada de acordo com as regras do Python, incluindo BOM e declaração na primeira ou segunda linha. Já tokenize.generate_tokens() trabalha com strings e não produz esse token.

ENDMARKER

ENDMARKER indica o final da entrada e aparece depois da última linha.

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

Ferramentas que consomem streams devem processar esse marcador para fechar estruturas e validar que toda a entrada foi lida.

OP e operadores exatos

O módulo tokenize costuma reportar operadores e delimitadores como OP.

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

Para distinguir +=, **, parênteses e outros símbolos, consulte TokenInfo.exact_type.

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

Assim, o token genérico OP pode ser refinado para PLUSEQUAL, DOUBLESTAR, LPAR e outras constantes.

EXACT_TOKEN_TYPES

token.EXACT_TOKEN_TYPES mapeia o texto de operadores e delimitadores para o tipo exato.

print(token.EXACT_TOKEN_TYPES["+"] == token.PLUS)
print(token.EXACT_TOKEN_TYPES[":="] == token.COLONEQUAL)
print(token.EXACT_TOKEN_TYPES["->"] == token.RARROW)

Esse mapa é útil quando uma ferramenta já possui o texto do símbolo e precisa obter a constante correspondente.

Operadores e delimitadores importantes

O módulo define constantes para parênteses, colchetes, chaves, vírgula, dois-pontos, ponto, operadores aritméticos, comparações, atribuições compostas, seta de anotação, walrus e outros símbolos.

Não construa uma tabela manual. Novas versões podem acrescentar tokens, como ocorreu com COLONEQUAL e EXCLAMATION.

F-strings

Versões atuais expõem tokens específicos para partes de f-strings: FSTRING_START, FSTRING_MIDDLE e FSTRING_END.

mensagem = f"Olá, {usuario.nome}!"

O início inclui prefixo e aspas de abertura. O conteúdo literal aparece em partes intermediárias, enquanto expressões de substituição usam os tokens normais do Python delimitados por chaves e símbolos de formatação.

Ferramentas que analisam f-strings devem testar a versão alvo, porque a tokenização evoluiu junto com a gramática.

Template strings no Python 3.14

O Python 3.14 adicionou TSTRING_START, TSTRING_MIDDLE e TSTRING_END para template string literals.

Uma ferramenta compatível com várias versões não deve presumir que essas constantes existem.

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

Use detecção de recurso ou uma matriz explícita por versão, especialmente em linters distribuídos como pacote.

SOFT_KEYWORD

SOFT_KEYWORD existe como constante para usos internos, mas o módulo tokenize não a produz normalmente. Uma soft keyword tende a chegar como NAME.

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

O contexto sintático decide se a palavra realmente exerce função especial. Para certeza estrutural, analise a AST.

ERRORTOKEN

ERRORTOKEN representa entrada inválida em algumas situações. Entretanto, tokenize também pode lançar exceções como TokenError ou produzir tokens que só serão rejeitados posteriormente pelo parser.

try:
    tokens = list(tokenize.generate_tokens(iter([codigo]).__next__))
except tokenize.TokenError as erro:
    print("entrada incompleta ou inválida", erro)

Não dependa apenas de ERRORTOKEN para validar sintaxe.

TYPE_COMMENT e TYPE_IGNORE

TYPE_COMMENT e TYPE_IGNORE são usados em fluxos que reconhecem comentários de tipagem com flags específicas do compilador.

x = carregar()  # type: Resultado
ignorar()       # type: ignore

O tokenizer público não produz esses tipos em todos os modos. Ferramentas de tipagem geralmente trabalham com AST configurada para preservar type comments.

ISTERMINAL()

token.ISTERMINAL(valor) informa se o código representa um token terminal.

print(token.ISTERMINAL(token.NAME))

Essa função aparece principalmente em ferramentas que lidam com árvores do parser ou tabelas de gramática.

ISNONTERMINAL()

ISNONTERMINAL() verifica valores de símbolos não terminais, que representam regras compostas da gramática.

def classificar(codigo):
    if token.ISTERMINAL(codigo):
        return "terminal"
    if token.ISNONTERMINAL(codigo):
        return "não terminal"
    return "desconhecido"

APIs modernas costumam usar AST em vez da antiga árvore concreta, mas essas funções ainda são úteis em infraestrutura de parsing.

ISEOF()

ISEOF() identifica o marcador de fim da entrada.

assert token.ISEOF(token.ENDMARKER)

Ele evita acoplamento a um número específico e mantém a intenção explícita.

N_TOKENS

N_TOKENS indica a quantidade de tipos de token definida pela versão atual.

print(token.N_TOKENS)

Não use esse valor para persistir um formato próprio sem versão. A quantidade e os códigos podem mudar.

Valores mudam entre versões

A documentação deixa claro que os números não são uma API estável entre releases. Salvar apenas o inteiro em banco e interpretá-lo em outro Python pode produzir significado incorreto.

Ao persistir resultados, grave o nome simbólico e a versão do Python.

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

Formatadores e refatoradores

Uma ferramenta que precisa preservar comentários e espaçamento pode transformar a sequência de tokens e reconstruir o código com tokenize.untokenize().

novos = []
for item in tokens:
    if item.type == token.NAME and item.string == "antigo_nome":
        item = item._replace(string="novo_nome")
    novos.append(item)

resultado = tokenize.untokenize(novos)

Renomear corretamente exige análise de escopo. Combine tokens com symtable ou AST para evitar trocar atributos, variáveis locais e textos sem relação.

Linters

Linters podem detectar operadores proibidos, comentários especiais, números com estilo inconsistente e indentação. O tipo exato melhora a precisão.

if item.exact_type == token.COLONEQUAL:
    registrar_uso_walrus(item.start)

Associe sempre posição e linha original ao diagnóstico.

Testar em várias versões

Crie uma matriz de CI com todas as versões suportadas. Verifique tokens adicionados ou removidos, comportamento de f-strings, soft keywords e operadores.

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

Não baseie compatibilidade apenas no número principal. Mudanças podem ocorrer em releases menores da ferramenta que você usa.

Segurança

Tokenizar não executa o código, mas também não garante segurança. Um arquivo pode consumir muita memória, explorar casos extremos do parser ou conter código malicioso que será perigoso se executado depois.

Defina limites de tamanho, tempo e profundidade. Nunca passe automaticamente o resultado para eval() ou exec().

Erros frequentes

  • Comparar tipos com números literais.
  • Confundir token com tokenize.
  • Tratar todo OP como o mesmo operador.
  • Ignorar exact_type.
  • Confundir NL e NEWLINE.
  • Presumir que soft keywords chegam como SOFT_KEYWORD.
  • Persistir códigos sem a versão do Python.
  • Executar código apenas porque foi tokenizado com sucesso.

Boas práticas

  • Compare com constantes simbólicas.
  • Use tok_name em logs.
  • Consulte exact_type para operadores.
  • Preserve posição e linha original.
  • Detecte recursos novos com segurança.
  • Teste todas as versões suportadas.
  • Combine tokens com AST e symtable.
  • Imponha limites a entradas externas.

Conclusão

O módulo token no Python define o vocabulário usado para classificar elementos léxicos do código-fonte. Ele fornece constantes legíveis para nomes, números, strings, operadores, indentação, f-strings, template strings e marcadores internos.

Usado junto com tokenize, keyword, AST e tabelas de símbolos, ele permite construir analisadores e transformadores precisos sem depender de números instáveis. A regra principal é simples: trabalhe com nomes simbólicos, considere a versão do Python e nunca confunda análise sintática com execução segura.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Código-fonte representando palavras reservadas e soft keywords no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    keyword no Python: palavras reservadas

    Aprenda keyword no Python para validar identificadores, palavras reservadas e soft keywords conforme a versão do interpretador.

    Ler mais

    Tempo de leitura: 7 minutos
    07/08/2026
    Arquitetura de software representando classes abstratas com abc no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    abc no Python: classes abstratas

    Aprenda abc no Python para criar classes abstratas, métodos obrigatórios, subclasses virtuais e contratos de runtime.

    Ler mais

    Tempo de leitura: 6 minutos
    06/08/2026
    Código e estruturas representando tipos do runtime com o módulo types no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    types no Python: tipos do runtime

    Aprenda types no Python para usar SimpleNamespace, MappingProxyType, tipos do runtime e criação dinâmica de classes.

    Ler mais

    Tempo de leitura: 6 minutos
    06/08/2026
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    sched no Python: agende eventos

    Aprenda sched no Python para agendar eventos, controlar prioridades, cancelar tarefas e criar repetições com relógio monotônico.

    Ler mais

    Tempo de leitura: 8 minutos
    05/08/2026
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    atexit no Python: execute limpeza ao sair

    Aprenda atexit no Python para executar limpeza no encerramento, controlar ordem LIFO e evitar problemas com threads, sinais e exceções.

    Ler mais

    Tempo de leitura: 7 minutos
    05/08/2026
    Monitor com código binário representando análise de opcodes pickle com pickletools no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    pickletools no Python: analise pickles

    Aprenda pickletools no Python para desmontar pickles, analisar opcodes e otimizar fluxos sem executar dados não confiáveis.

    Ler mais

    Tempo de leitura: 7 minutos
    05/08/2026