15 pontos por GN⁺ 2025-04-22 | 2 comentários | Compartilhar no WhatsApp
  • t-strings (strings de template) são um novo recurso de processamento de strings seguro e flexível introduzido no Python 3.14
  • Diferentemente das f-strings existentes, uma t-string retorna um objeto Template, não uma string, permitindo processamento seguro sem saída automática
  • As t-strings têm uma estrutura que permite escapar com segurança entradas dinâmicas em HTML, SQL e outros contextos
  • É um conceito semelhante aos tagged templates do JavaScript, permitindo várias extensões de transformação e processamento
  • Se o ecossistema de ferramentas de desenvolvimento Python oferecer bom suporte a esse recurso, ele poderá provocar uma grande mudança no processamento de strings voltado para web/segurança

Novo recurso do Python: t-strings (Template Strings)

  • A partir do Python 3.14, as strings de template (t-strings), usadas com a sintaxe t"...", passam a fazer parte oficial da linguagem
  • Diferentemente das f-strings existentes, uma t-string é avaliada como um objeto string.templatelib.Template, e não imediatamente como string
  • Esse objeto exige uma etapa de processamento separada antes da saída, e por meio desse processo é possível fazer tratamento e transformação seguros de valores dinâmicos

Por que f-strings podem ser perigosas?

  • Como as f-strings são avaliadas imediatamente como string, em códigos que incluem entrada do usuário podem ocorrer SQL Injection ou XSS
    • Exemplo: f"<div>{user_input}</div>" → código malicioso pode ser inserido diretamente
  • As t-strings adiam essa avaliação, fazendo com que só possam ser usadas após processamento explícito

Exemplo de uso de t-strings

  • Exemplo de escape de HTML:

    evil = "<script>alert('bad')</script>"  
    template = t"<p>{evil}</p>"  
    safe = html(template)  
    # safe é "<p>&lt;script&gt;alert('bad')&lt;/script&gt;</p>"  
    
  • Também é possível fazer processamentos mais complexos, como inserção automática de atributos:

    attributes = {"src": "roquefort.jpg", "alt": "Yum"}  
    template = t"<img {attributes} />"  
    element = html(template)  
    # resultado: "<img src='roquefort.jpg' alt='Yum' />"  
    

Estrutura e API

  • O objeto Template fornece separadamente o texto original e os valores interpolados por meio dos atributos .strings e .values

  • Pelo atributo interpolations, também é possível acessar detalhes de formatação como !s, :>8 e outros

  • Pela iteração, também é possível processar diretamente o estado misto de texto e valores

  • A criação manual também é possível:

    from string.templatelib import Template, Interpolation  
    template = Template(  
      "Hello ",  
      Interpolation(value="World", expression="name"),  
      "!"  
    )  
    

Exemplo divertido: conversor para Pig Latin

  • Exemplo que percorre o conteúdo do objeto Template e transforma palavras em Pig Latin:

    def pig_latin(template: Template) -> str:  
        ...  
    name = "world"  
    template = t"Hello {name}!"  
    assert pig_latin(template) == "Hello orldway!"  
    

Direção futura de evolução

  • As t-strings podem trazer segurança e extensibilidade ao processamento de strings voltado para web/segurança
  • Espera-se que ferramentas de desenvolvimento como black, ruff e VS Code passem a oferecer suporte a formatação/destaque para t-strings
  • Como são semelhantes ao modelo de tagged templates com o qual desenvolvedores JavaScript já estão familiarizados, há grande potencial de uso em vários frameworks

Colaboração com a comunidade de desenvolvedores

  • Esse recurso foi concluído com a participação e colaboração de vários membros da comunidade Python
  • Em especial, são mencionadas interações com figuras-chave como Jim, Paul, Koudai, Lysandros e Guido
  • O PEP 750 e seu repositório de exemplos podem ser consultados no GitHub

O recurso de t-strings do Python 3.14 garante ao mesmo tempo segurança e extensibilidade para strings, representando um salto importante além das limitações das f-strings

2 comentários

 
GN⁺ 2025-04-22
Comentários do Hacker News
  • No geral, esse recurso é bem legal. Basicamente, ele transforma um código como este

    db.execute("QUERY WHERE name = ?", (name,))
    

    em algo assim

    db.execute(t"QUERY WHERE name = {name}")
    

    Há a questão de saber se esse açúcar sintático traz benefícios suficientes para justificar a complexidade de um novo recurso da linguagem. Acho que, neste caso, sim, por dois motivos

    • é bom permitir que desenvolvedores de bibliotecas façam o que quiserem com a expansão de {}, e isso provavelmente vai gerar bons casos de uso
    • provavelmente também é bom generalizar a sintaxe de templates em toda a linguagem, para que todas as bibliotecas resolvam o problema da mesma forma
  • Também espero que o ecossistema de ferramentas se adapte para dar suporte a t-strings. Por exemplo, seria bom se black e ruff formatassem o conteúdo de t-strings, e se o vscode destacasse com cores conteúdos de tipos comuns, como HTML ou SQL

    • essa visão sobre t-strings é bem estranha. A única forma de inferir que uma string de template deve se transformar em HTML ou SQL válidos seria com base na sintaxe aparente da string, algo que só pode ser feito de forma improvisada e que não tem relação com o recurso de template string em si
    • na forma como o recurso foi projetado, não há nenhuma indicação na própria string sobre que tipo de conteúdo ela contém ou no que ela vai se transformar ao final. Tudo é tratado pela função de conversão
    • como outras pessoas acrescentaram, algo como sql”select * from {table}” poderia fazer isso, mas não há garantia de que o que está no template será convertido em SQL válido pela função de conversão. t“give me {table} but only {columns}” pode se transformar em SQL válido depois que o template for processado
  • Será que poderíamos usar uma sintaxe SQL elegante como esta?

    city = 'London'
    min_age = 21
    # Find all users in London who are 21 or older:
    users = db.get(t'
      SELECT * FROM users
      WHERE city={city} AND age>{min_age}
    ')
    

    Se a função db.get() aceitar templates, então sim. Seria a forma mais elegante de usar SQL que já vi até agora

  • Pessoalmente, acho que esse recurso está focado demais em um problema específico para virar uma funcionalidade geral. Python está ficando cada vez maior. Quando as pessoas perguntam se Python é fácil e simples de aprender, temos que responder: "o básico sim, mas aprender a linguagem inteira não"

    • nesse aspecto, Go é interessante por rejeitar quase todo recurso novo. Sinceramente, não tenho certeza de que generics valham a pena, porque adicionam muita complexidade. Acho correta a ideia geral de manter a linguagem alinhada com seu foco original. C++ talvez seja o caso extremo, em que a linguagem quase não se parece mais com o que era no começo
  • Grande discussão (414 pontos, há 10 dias, 324 comentários) link

  • Bem legal. Se estão portando recursos de JS, será que o próximo passo é ganhar unpacking/destructuring de dicionários?

    • eu quero muito esse recurso. É o principal motivo de eu voltar para JS
    >>> {a, b=45, c=None, **d} = {'a': 234, xzy: 32456}
    >>> print(a, b, c, d)
    234 45 None {'xyz': 32456}
    
  • Só o fato de esse novo recurso x-string ser embutido já parece uma "trapaça". Seria legal se fosse possível fazer algo como

    from foo import bar
    bar"zoop"
    
  • Zen of Python em 2025:

    There should be one-- and preferably only one --obvious way to do it.
    

    Formatação de strings em Python em 2025:

    • t-strings
    • f-strings
    • operador %
    • operador +
    • str.format()
  • Não entendo como isso é diferente de aplicar uma função ao template em vez de aplicá-la à variável dentro de uma f-string. Então, em vez de fazer algo como:

    evil = "<script>alert('bad')</script>"
    template = t"{evil}"
    safe = html(template)
    

    por que não simplesmente fazer isto:

    evil = "<script>alert('bad')</script>"
    safe = f"{html(evil)}"
    

    Ou então antes de criar a f-string. Será que a ideia é simplesmente garantir que você não esqueça a parte de sanitização/manipulação de string e seja forçado a passar por ela?

  • Olá! Eu escrevi esse post :-)

    • cheguei um pouco tarde à conversa e fiquei um pouco surpreso ao ver este post virar tendência no HN, mas ficarei feliz em responder perguntas. Vou tentar participar ao longo do dia, nos intervalos