PEP 750 – Template Strings
Purpose and core semantics
- t-strings (
t"...") produce aTemplateobject, not astr. - A
Templateholds two sequences: literal string segments and “interpolations” (expressions), preserving which parts are static vs dynamic. Templatedeliberately 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 plainstr, 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.formatandstring.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.