As t-strings são uma novidade do Python 3.14 criada para representar textos interpolados de forma estruturada. Elas usam uma sintaxe parecida com as f-strings, mas não produzem imediatamente uma string final. Em vez disso, retornam um objeto de template que separa as partes literais do texto, os valores interpolados e informações como conversão e especificação de formato. Essa diferença permite validar, escapar, transformar ou auditar os valores antes de montar a saída definitiva.
O recurso é exposto pelo módulo string.templatelib e é especialmente útil em situações nas quais juntar texto e dados diretamente seria arriscado ou pouco flexível. Entre os exemplos estão geração de HTML, criação de consultas, construção de logs estruturados, internacionalização e ferramentas que precisam entender quais valores foram inseridos em um texto.
O que muda em relação às f-strings
Uma f-string avalia as expressões e devolve uma instância de str. Isso é ótimo para mensagens simples, mas a estrutura original desaparece. Depois que o texto foi montado, fica difícil saber quais trechos eram literais e quais vieram de variáveis. Já uma t-string preserva essa estrutura. O resultado contém partes estáticas e objetos de interpolação, permitindo que outro componente decida como cada valor será processado.
nome = "Ana"
idade = 28
modelo = t"Usuário: {nome}, idade: {idade}"
print(type(modelo))
print(modelo.strings)
print(modelo.interpolations)Nesse exemplo, modelo não é uma string comum. O atributo strings contém os segmentos literais, enquanto interpolations reúne os valores inseridos. O consumidor pode percorrer essas partes e aplicar regras específicas antes de produzir a saída.
Template e Interpolation
O módulo define principalmente as classes Template e Interpolation. Um Template representa a sequência completa. Cada Interpolation guarda o valor avaliado, o texto da expressão, uma conversão opcional e a especificação de formato. Isso permite reproduzir recursos familiares das f-strings sem perder os metadados.
Por exemplo, uma interpolação como {preco:.2f} preserva o valor e a especificação .2f. Um processador pode respeitar essa formatação, rejeitá-la ou substituí-la por outra regra. Da mesma forma, conversões como !r podem ser inspecionadas antes de serem aplicadas.
Como percorrer uma t-string
O objeto de template pode ser percorrido. Durante a iteração, ele fornece strings literais e objetos de interpolação na ordem em que aparecem. Isso facilita a criação de renderizadores pequenos e explícitos.
from string.templatelib import Interpolation
def renderizar(template):
partes = []
for item in template:
if isinstance(item, Interpolation):
partes.append(str(item.value))
else:
partes.append(item)
return "".join(partes)
usuario = "Carlos"
print(renderizar(t"Olá, {usuario}!"))Esse renderizador é intencionalmente simples. Em uma aplicação real, ele poderia tratar cada tipo de valor, aplicar escape de HTML, ocultar dados sensíveis ou gerar uma estrutura diferente de uma string.
Escape seguro para HTML
Um dos usos mais interessantes é a renderização segura. Inserir dados externos diretamente em HTML pode criar vulnerabilidades quando o conteúdo não é escapado. Com t-strings, o renderizador consegue escapar apenas os valores interpolados, preservando os trechos literais escritos pelo desenvolvedor.
from html import escape
from string.templatelib import Interpolation
def html_seguro(template):
saida = []
for item in template:
if isinstance(item, Interpolation):
saida.append(escape(str(item.value)))
else:
saida.append(item)
return "".join(saida)
comentario = "<script>alert('x')</script>"
pagina = html_seguro(t"<p>{comentario}</p>")O ponto importante é que a segurança não acontece automaticamente apenas por usar uma t-string. Ela fornece a estrutura necessária para implementar uma política segura. O renderizador continua responsável por escolher o tratamento correto para cada contexto.
Logs estruturados
Outra aplicação é registrar mensagens sem perder os campos originais. Em vez de criar apenas um texto pronto, um sistema de logging pode armazenar o modelo, os nomes das expressões e seus valores separadamente. Isso melhora filtros, métricas e buscas.
def registrar(template):
campos = {}
for interp in template.interpolations:
campos[interp.expression] = interp.value
print({"mensagem": template.strings, "campos": campos})
pedido_id = 845
status = "pago"
registrar(t"Pedido {pedido_id} ficou {status}")Essa abordagem é mais útil do que analisar uma mensagem pronta depois. Os dados continuam tipados e podem ser enviados a ferramentas de observabilidade sem parsing frágil.
Validação de consultas e comandos
T-strings também podem ser usadas como entrada de bibliotecas que geram consultas ou comandos. Um processador pode aceitar apenas determinados tipos, transformar parâmetros em placeholders e rejeitar expressões inadequadas. Isso evita a concatenação manual de dados em textos sensíveis.
É importante não tratar uma t-string como proteção automática contra SQL injection ou command injection. A biblioteca que consome o template deve implementar parametrização real. A vantagem é ter acesso às partes separadas, facilitando a criação dessa implementação.
Formatação e conversão
As t-strings preservam format_spec e conversion, mas o renderizador decide quando aplicá-los. A função convert() do módulo pode aplicar conversões compatíveis, enquanto a formatação pode ser feita com format(). Essa separação é útil porque permite restringir formatos ou aplicar regras específicas por tipo.
from string.templatelib import Interpolation, convert
def renderizar_formatado(template):
resultado = []
for item in template:
if not isinstance(item, Interpolation):
resultado.append(item)
continue
valor = convert(item.value, item.conversion)
resultado.append(format(valor, item.format_spec))
return "".join(resultado)Ao criar um renderizador, trate cuidadosamente especificações vazias, conversões ausentes e objetos que implementam métodos de formatação personalizados.
Quando usar
Use t-strings quando a estrutura da interpolação tiver valor para a aplicação. Elas são adequadas para sistemas de templates, logs estruturados, geração segura de marcação, internacionalização, DSLs e bibliotecas que precisam validar valores. Para mensagens simples exibidas diretamente ao usuário, uma f-string continua sendo mais curta e suficiente.
Também vale considerar compatibilidade. T-strings exigem Python 3.14 ou superior. Bibliotecas que suportam versões anteriores precisam oferecer um caminho alternativo ou declarar a versão mínima. Consulte o guia de Type Hints no Python, o artigo sobre f-strings para depuração, o conteúdo de introspecção com inspect e a seção de Python Avançado para ampliar o contexto.
Boas práticas
Mantenha o renderizador pequeno, testável e específico para o contexto. Não use o mesmo escape para HTML, SQL, shell e URLs, pois cada destino possui regras diferentes. Valide tipos aceitos, registre erros com clareza e evite executar código adicional durante a renderização. Teste valores vazios, caracteres especiais, objetos personalizados e especificações de formato inválidas.
Para detalhes da linguagem, consulte a documentação oficial de string.templatelib e a PEP 750, que descreve a motivação e o modelo das template strings.
Conclusão
T-strings não substituem as f-strings em todos os casos. Elas resolvem outro problema: preservar a estrutura de um texto interpolado para que uma biblioteca possa tomar decisões seguras e inteligentes. Ao separar conteúdo literal, valores, conversões e formatos, string.templatelib abre espaço para renderizadores, logs e ferramentas mais robustos. O ganho principal não é escrever menos código, mas manter controle sobre como os dados se transformam em texto.







