The Problem with Early Flattening

F-strings are excellent for human-readable display but suffer from a fundamental limitation: they collapse structured information into a plain str immediately upon evaluation. Once interpolated, the boundary between static text and dynamic data is lost. This makes it impossible for downstream processes to distinguish between trusted markup and untrusted runtime values, leading to common vulnerabilities like SQL injection or HTML/script injection.

How T-Strings Preserve Structure

Unlike f-strings, which return a str, t-strings (using the t prefix) return a string.templatelib.Template object. This object preserves the literal text, the evaluated interpolation values, the original expression text, and any format specifications.

Crucially, t-strings are not lazy. Expressions inside the braces are evaluated eagerly, just like f-strings. The innovation is not in deferred execution, but in delayed combination. By keeping the pieces separate, developers can write custom renderers that apply domain-specific logic—such as context-aware HTML escaping or parameterizing SQL queries—before the final string is produced.

Practical Applications for Library Design

  • SQL Construction: Instead of concatenating values into a query string, a t-string renderer can extract values as parameters, allowing the database driver to handle them safely.
  • Structured Logging: Renderers can extract interpolation expressions as structured fields (e.g., user_id) while simultaneously generating a human-readable message, eliminating the need for redundant extra dictionaries.
  • Domain-Specific Formatting: Because format specifications (like .2f) are preserved as data, library authors can define custom formatters (e.g., :currency) that go beyond standard Python numeric formatting.

When to Use (and Avoid) T-Strings

  • Use for: Boundary-sensitive code where the target domain requires specific handling of data (HTML, SQL, shell commands, audit logs, LLM prompts).
  • Avoid for: Ordinary human-readable messages. If the goal is simply to produce a string, f-strings remain the superior, more readable choice.
  • Security Warning: T-strings are not a security panacea. They do not magically secure your code; they provide the structure necessary for a well-written renderer to enforce security policies. Furthermore, they are Python expressions, not sandboxed templates; they should never be used for untrusted user-authored templates.