Title: string.Template does not allow step-by-step replacements
Type: enhancement Stage: test needed
Components: Library (Lib) Versions: Python 3.2
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: barry Nosy List: BreamoreBoy, barry, mrabarnett, rhettinger, scoder
Priority: low Keywords: patch

Created on 2005-03-07 11:50 by scoder, last changed 2010-08-11 22:17 by rhettinger. This issue is now closed.

File name Uploaded Description Edit
from_template.diff mrabarnett, 2010-07-10 16:49
Messages (5)
msg54409 - (view) Author: Stefan Behnel (scoder) * (Python committer) Date: 2005-03-07 11:50
A common use case for templates is partially replacing
placeholders in loops or method cascades. The
safe_substitute method of the Template class provides
rudimentary support for this as long as Templates do
not contain the "$$" escape. In cases where multiple
replacements are necessary, a new Template must be
created. This messes up the "$$" replacement.

An example:

.>>> from string import Template
.>>> a = Template('$a + $$ != $b')
.>>> b = Template(a.safe_substitute(a=1))
.>>> [ b.substitute(b=i) for i in range(3) ]
Traceback [...]
ValueError: Invalid placeholder in string: line 1, col 5

In the current implementation, there is no way of
getting around this problem.

I suggest adding a new class-method as constructor to
the Template class: "Template.from_template", that
takes a template, applies a safe_substitute with the
provided (kw)arguments and returns a *valid* Template
(not a string). However, this method *must not* replace
occurrences of "$$" in the original template.

The above example would then look like this:
.>>> from string import Template
.>>> a = Template('$va + $$ != $vb')
.>>> b = Template.from_template(a, va=1)
.>>> [ b.substitute(vb=i) for i in range(3) ]
[ '1 + $ != 0', '1 + $ != 1', '1 + $ != 2' ]
msg109745 - (view) Author: Mark Lawrence (BreamoreBoy) * Date: 2010-07-09 14:33
Stefan, could you provide a patch to move this forward, can this issue be closed, or what?
msg109889 - (view) Author: Matthew Barnett (mrabarnett) * (Python triager) Date: 2010-07-10 16:49
Here's a patch for Python 3.1, if anyone's still interested after 5 years. :-)
msg110159 - (view) Author: Stefan Behnel (scoder) * (Python committer) Date: 2010-07-13 06:05
I actually am no longer interested (after 5 years), but if the patch solves the problem, it'd be good to apply it. Lacks a docs patch, though.
msg113636 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2010-08-11 22:17
FWIW, the $name $$ $(name) convention is used many other contexts and I don't think there is usually support provided to not substitute $$.  Even if there were, there is a usability issue where the final substitution needs to be applied differently to get the effect of escaping.  Since the final step needs to be different anyway, it is no burden to just use the current string.Template and write $(dollar_sign) in-place of $$ and apply that substitution on the final step.

Also, the current API for extending string.Template is already complex.  IMO, it is not a good idea to add more options to something that was supposed to provide a simpler alternative to templating.
Date User Action Args
2010-08-11 22:17:47rhettingersetstatus: open -> closed

nosy: + rhettinger
messages: + msg113636

resolution: rejected
2010-08-11 20:09:52rhettingersetpriority: normal -> low
2010-08-09 04:15:05terry.reedysetversions: + Python 3.2, - Python 3.1
2010-07-13 06:05:06scodersetmessages: + msg110159
2010-07-10 16:49:05mrabarnettsetfiles: + from_template.diff

nosy: + mrabarnett
messages: + msg109889

keywords: + patch
2010-07-09 14:40:20BreamoreBoysetversions: + Python 3.1, - Python 2.7
2010-07-09 14:33:27BreamoreBoysetnosy: + BreamoreBoy
messages: + msg109745
2009-02-15 23:42:13ajaksu2setstage: test needed
versions: + Python 2.7
2005-03-07 11:50:56scodercreate