Yes, it shouldn’t be anything major.
We have published the list of changes here: PEP 750 -- Template Strings · Issue #275 · python/steering-council · GitHub
As we mention in the issue, you can make these changes in parallel to the implementation (so don’t wait until the PEP is modified and is officially approved to propose and iterate over the PR). But landing the PR requires the PEP approved.
I’m super excited for this feature! Is this still expected to make it into 3.14?
@dkp @lys.nikolaou would it help if I attempt to make a PR tomorrow to the tstrings branch of Lysandros’s fork that does the rename of expr/conv and the move of the Template/Interpolation types?
That’s the plan, there’s a month until the feature freeze on 2025-05-06.
Sure, I’d be happy to accept a PR with the requested changes.
My PR is posted. The chances of this making tomorrow’s alpha are pretty slim, correct?
The implementation will only be merged if the PEP is accepted, which hasn’t happened yet:
landing the PR requires the PEP approved.
Per Hugo’s note above, there’s still a month before actual feature freeze, so there’s no mad rush (yet!).
A
Ah okay, so it will most likely first ship in beta 1. Thanks!
Thanks, @pablogsal!
PEP 750 has been updated with a first cut addressing steering council feedback. Thanks to everyone who helped!
If you’d like to play with t-strings, see Lysandros’ branch or grab a docker image. The pep750-examples repo has also been updated; it includes a devcontainer.
The Steering Council reviewed today PEP 750: Updates requested by the Steering Council by davepeck · Pull Request #4351 · python/peps · GitHub and we are happy with the changes so we are formally approving the PEP. Congratulations yet again! ![]()
Looks really nice, but two things I really found surprising:
- No i18n example in the PEP itself. Like, that seems to be THE perfect usecase for this. No more
_('Hello {}').format(name)- instead, you do_(t'Hello {name}')and all this needs is your gettext function (and string extractor) to have support for it (which sounds pretty trivial) - Convoluted logging example:
logging.info(_(t"User {action}: {amount:.2f} {item}")):_()is typically i18n, so that shortcut is weird- People will absolutely forget this and then wonder why their logging is not working as expected. Instead, why not support this inside logging (I think the example repo actually does it that way, but the PEP will be read by MANY more people)
I raised this during the first round of discussions so won’t repeat myself here except to point you to the flufl.i18n library I maintain.
Yeah.
I wrote the first logging example in the PEP to directly parallel Python’s current documentation on how to implement structured logging. That documentation also adopts _ and has the drawback you mentioned: it’s easy to forget.
I have a strong preference for the second logging example in the PEP but felt like it was important to work with existing documentation first.
Maybe it’s worth revisiting this as part of our work towards documenting t-strings for 3.14’s release.
FWIW, when doing logging customisation on input (which is the only way you can do it consistently in a library that doesn’t control the overall logging config), I don’t do the wrapping at every call site, but provide a logging facade that mirrors the stdlib logging APIs.
Adding t-string support would happen in the facade layer rather than at every call site.
Naming question: Is Template alone readable enough, or should we spend some more letters for the more specific TemplateStr? Sure, the fully qualified name string.templatelib.Template is unambiguous, but I anticipate that it will typically be imported via from string.templatelib import Template so that typical code usage is (snippets taken from the PEP)
template: Template = t"Hello {name}"
# or
def html(template: Template) -> Element:
and there I would find TemplateStr more readable compared to a generic Template
template: TemplateStr = t"Hello {name}"
# or
def html(template: TemplateStr) -> Element:
I would prefer TemplateStr or TemplateString to deconflict with string.Template. However, the PEP has already been accepted so I don’t think it can change?
The PEP cannot change, it is a historical document. The implementation can be updated with a new PEP, but you will have to convince others that this change is worth making.
I’m not totally sure what your comment means specifically, but it is worth searching the discussion to see if this came up and was resolved already.
There’s always “import as” to handle any ambiguity.
I’ve searched here, in PEP 750: Tag Strings For Writing Domain-Specific Languages - PEPs - Discussions on Python.org and the PEP itself and found no discussion on the naming of Template. That’s why I’m bringing up the question here - Addmittedly I haven’t read all posts but tried different search patterns, so I might have overlooked something. I’d be happy to see this has been discussed and decided before.
There’s always “import as” to handle any ambiguity.
Sure. The question is, what is the intended naming in user code. A single user can always do from string.templatelib import Template as TemplateStr to have a better name. But IMHO we shouldn’t generally recommend renaming via as if we have the possibility to choose the name ourselves. Naming is important. There are arguments for both Template and TemplateStr. I just want to make sure this decision is conscious.
Maybe something closer to TTemplate if that is an issue?
TemplateStr is ambiguous as it can as well mean string.Template. Also not very pleasant.