[Python-Dev] Re: Alternative Implementation
forPEP292:SimpleString Substitutions
Raymond Hettinger
raymond.hettinger at verizon.net
Fri Sep 10 07:50:40 CEST 2004
[Barry]
> And to make effbot and Raymond happy, it won't auto-promote to unicode
> if everything's an 8bit string.
Glad to see that my happiness now ranks as a development objective ;-)
> There will be updated unit tests, and I will update the documentation
> and the PEP as appropriate -- if we've reached agreement on it.
+1
Beautiful job.
Barry asked me to bring up one remaining implementation issue for
discussion on python-dev.
The docs clearly state that only python identifiers are allowed as
placeholders:
[_A-Za-z][_A-Za-z0-9]*
The challenge is that templates can be exposed to non-programmer
end-users with no reason to suspect that one letter of their alphabet is
different from another. So, as it stands right now, there is a
usability issue with placeholder errors passing silently:
>>> fechas = {u'hoy':u'lunes', u'mañana':u'martes'}
>>> t = Template(u'¿Puede volver $hoy o $mañana?')
>>> t.safe_substitute(fechas)
u'¿Puede volver lunes o $mañana?'
The substitution failed silently (no ValueError as would have occurred
with $@ or a dangling $). It may be especially baffling for the user
because one placeholder succeeded and the other failed without a hint of
why (he can see the key in the mapping, it just won't substitute). No
clue is offered that the Template was looking for $ma, a partial token,
and didn't find it (the situation is even worse if it does find $ma and
substitutes an unintended value).
I suggest that the above should raise an error:
ValueError: Invalid token $mañana on line 1, column 24
It is easily possible to detect and report such errors (see an example
in nondist/sandbox/string/curry292.py).
The arguments against such reporting are:
* Raymond is smoking crack. End users will never make this mistake.
* The docs say python identifiers only. You blew it. Tough. Not a
bug.
* For someone who understands exactly what they are doing, perhaps $ma
is the intended placeholder -- why force them to uses braces:
${ma}ñana.
In addition to the above usability issue, there is one other nit. The
new invocation syntax offers us the opportunity for to also accept
keyword arguments as mapping alternatives:
def substitute(self, mapping=None, **kwds):
if mapping is None:
mapping == kwds
. . .
When applicable, this makes for beautiful, readable calls:
t.substitute(who="Barry", what="mailmeister", when=now())
This would be a simple and nice enchancement to Barry's excellent
implementation. I recommend that keyword arguments be adopted.
Raymond
More information about the Python-Dev
mailing list