PEP 750 – Template Strings

Purpose and core semantics

  • t-strings (t"...") produce a Template object, not a str.
  • A Template holds two sequences: literal string segments and “interpolations” (expressions), preserving which parts are static vs dynamic.
  • Template deliberately has no meaningful __str__; you must pass it to a rendering function (e.g. html(), SQL library, custom formatter).

Use cases discussed

  • HTML: embed HTML directly in Python with t-strings, then pass to an HTML library that escapes user content and enforces correct markup.
  • SQL: build parameterized queries where the library can treat interpolations as parameters, avoiding manual placeholder management and reducing injection risk.
  • Logging: structured logs or deferred formatting by operating on the interpolation objects rather than parsed strings.
  • LLM prompts: treating prompts as templates whose variables and structure are inspectable.
  • i18n: possibility to localize templates while keeping placeholders as structured interpolations.

Security and injection debates

  • Advocates: libraries can require Template, refuse plain str, and safely escape all interpolations; this mirrors JavaScript tagged templates and should reduce HTML/SQL injection.
  • Critics: developers can still misuse unsafe formatting functions; security depends on library discipline, not syntax alone. Some see this as “more magic” and more failure modes.

Eager vs lazy evaluation

  • Interpolated expressions are evaluated eagerly, like f-strings; only string assembly is deferred.
  • Earlier lazy designs were dropped as too complex and confusing; explicit lambdas or wrapper functions are suggested for true deferred evaluation.
  • Some commenters argue that without deferral this isn’t a “template” in the usual sense; others note that you can still get reusable template factories via functions.

Tooling, syntax, and ergonomics

  • Strong interest in editor support: syntax highlighting and formatting for HTML/SQL inside t-strings.
  • Difficulty: templates don’t declare their language; tools may have to infer from function names or types.
  • Some wish Python had a lighter syntax (e.g. backtick literals) like JS; backticks are intentionally banned in Python’s grammar.

Relationship to existing mechanisms

  • Not a drop-in Jinja replacement: no control-flow in the template itself; more like “tagged literals” for libraries.
  • Compared with str.format and string.Template, t-strings are pre-parsed at compile time and preserve expression structure instead of using regex over raw text.
  • Many worry about “yet another” string formatting style (now %, .format, string.Template, f-strings, t-strings); others argue t-strings unify patterns and can underpin safer library APIs.