PEP 750: Tag Strings For Writing Domain-Specific Languages

There are a few topics going on, so I’ll respond to the topic rather than individuals.

Eager evaluation of interpolated values (i.e. the x+y in tag"{x+y}") is so much simpler to implement that we’d want to do that if at all possible. Deferring evaluation actually means evaluating in a different context, not just at a different time. If you think it’s easy, please go and help us get deferred evaluation of annotations sorted out, because it turns out that it’s so difficult we’ve delayed that for many releases at this stage. Eager evaluation would mean that the value of the expression is calculated in the context of the function, as if the author had written it as an assignment on the previous line.[1]

Arbitrary expressions as tags sounds pretty difficult. I’ll gladly defer entirely to @pablogsal on this one, and if he’s not enthusiastic about it, then I’m not either.

Nominal subtyping has no precedent in Python for this kind of thing. We’d do it with a protocol, which means a __something__ dunder method that is called when the object is used as a tag. If the method doesn’t exist, you’ll get a TypeError at runtime.[2]

Backticks are traditionally banned from use in future language features, due to the small symbol. No reader should need to distinguish ` from ' at a glance. It’s entirely possible that the prevailing opinion on this has changed, but it’s certainly going to be easier to stick to the letter prefixes and regular quotes.

Non-string results seem fine to me. I quite like Paul’s example of a decimal literal, and I can see great convenience in constructing XML literals for ElementTree, AST literals, or similar DSLs which would be wasted if we were to require string results. I expect we’re quite likely to see these used for strings with no substitutions as well, such as the py" example mentioned, and so it may be useful to address how a tagged string with no interpolations is meant to be handled, and whether (if it remains a normal callable) tag objects should be expected to be applied to string variables as well (e.g. do/should both xml"<a></a>" and xml("<a></a>") behave the same?)


  1. Using tag"{lambda: x+y}" with a tag that knows how to handle it is just fine. The semantics are complicated, and so the caller needs to know about it. ↩︎

  2. Type checkers can do whatever they want to warn you ahead of time, but that’s not how we implement the actual functionality. ↩︎

19 Likes