PEP 750: Please add Template.join()

Yes, that’s correct. Joiner strings are likely different in different contexts:

fields = t", ".join(list_of_fields)
conditions = t" AND ".join(list_of_conditions)
cur.execute(t"select {fields} from mytable where {contditions}")

This was proposed, yes, but it seems an abuse of Interpolation.format_spec. One need we have is to specify the parameter format - akin to using %s, %b, %t in psycopg. In the first experiment with template strings I am using:

  • :s or no format: bind the parameter server-side use the best format for the type, text or binary (similar to %s).
  • :b: bind the parameter server-side, send it in binary format
  • :t: bind the parameter server-side, send it in text format
  • :i: bind the parameter client-side with identifier escaping rules (similar to sql.Identifier, e.g. "foo-bar")
  • :l: bind the parameter client-side using SQL literal rules (similar to sql.Literal, or similar to using psycopg2, where all binding was client-side. e.g. 10, or 'foo''bar' or '2025-01-01'::date)

It would seems strange to me, in the same “laguage” (template strings to generate SQL), to have in certain places symbolic format specs and in other literal string to operate on. What tells the two apart? The fact that the value is a list? Psycopg can adapt lists too as Postgres arrays, so we should single out lists of templates and special-case their processing. And what if a list is empty? Is it an empty list of conditions to render client-side as an empty string or an empty array value to pass to the database as '{}'? It’s pretty brittle.

In this proposal, AND or , are the parameter of an operation (template joining), and the thing that I find unsatisfactory is that the operation is implicit. This burns all the bridges to be able to perform any other operations. If we want to be explicit, we should put the operation too in the format spec, so it might be:

t"{filters:join(' AND ')}"

but now I’m starting to need to write a Python parser to parse that, or to come out with an entirely new language… Yes, I can parse:

t"{filters:join~ AND )}"

or whatever else but that doesn’t make it a good idea :slight_smile:

Not to mention that, unlike in the value, I can’t reuse the same quotes of the t-string…

>>> t"{[]:join(" AND ")}"
  File "<python-input-1>", line 1
    t"{[]:join(" AND ")}"
          ^^^^^
SyntaxError: t-string: expecting '}', or format specs.

Therefore my preference is to describe the operation “join these snippets using this separator” as an external operation rather than cramming more than symbolic info in the format_spec.

4 Likes