The architecture of this seems really neat.
For example, since template literal expressions are arbitrary Python expressions, string literals could be used to indicate cases where evaluation itself is being deferred, not just rendering:
logging.debug(t"Logger: {'record.name'}; Event: {event}; Details: {data}")
It would be nice to be able to leverage some of this architecture to create t-strings with deferred evaluation at runtime: i.e., a way to convert a string (not necessarily literal!) like "Logger: {record.name}; Event: {event}; Details: {data}" explicitly at runtime into a TemplateLiteral instance equivalent to t"Logger: {'record.name'}; Event: {'event'}; Details: {'data'}". That would be huge for i18n purposes, for example: we could read the template string from a l10n resource bundle.
Yes; right now that can be done more or less by just using .format on an ordinary string. However, this would be more flexible (since it opens up the context-sensitive formatting machinery), potentially more powerful (as f-strings are), and potentially simpler to use (perhaps there could be some simple way to provide the formatter with the namespace to use for deferred evaluation, rather than passing each variable explicitly as a separate keyword argument or having to write weird stuff like **locals() only to miss out on outer scopes anyway).