The classes have been renamed Template and SafeTemplate. Also, a bunch of

open issues have been added.
This commit is contained in:
Barry Warsaw 2004-08-20 14:20:38 +00:00
parent b5815e3e63
commit 2042beaefb
1 changed files with 73 additions and 21 deletions

View File

@ -43,9 +43,9 @@ Rationale
A Simpler Proposal
We propose the addition of a new class -- called 'template', which
We propose the addition of a new class -- called 'Template', which
will live in the string module -- derived from the built-in
unicode type. The template class supports new rules for string
unicode type. The Template class supports new rules for string
substitution; its value contains placeholders, introduced with the
$ character. The following rules for $-placeholders apply:
@ -64,39 +64,39 @@ A Simpler Proposal
If the $ character appears at the end of the line, or is followed
by any other character than those described above, it is treated
as if it had been escaped, appearing in the resulting string
unchanged.
unchanged. NOTE: see open issues below.
No other characters have special meaning, however it is possible
to derive from the template class to define different rules for
to derive from the Template class to define different rules for
the placeholder. For example, a derived class could allow for
periods in the placeholder (e.g. to support a kind of dynamic
namespace and attribute path lookup).
Once the template has been created, substitutions can be performed
Once the Template has been created, substitutions can be performed
using traditional Python syntax. For example:
>>> from string import template
>>> from string import Template
>>> mapping = dict(name='Guido', country='the Netherlands')
>>> s = template('${name} was born in ${country}')
>>> s = Template('${name} was born in ${country}')
>>> print s % mapping
Guido was born in the Netherlands
Another class is provided which derives from template. This class
is called 'safe_template' and supports rules identical to those
above. The difference between template instances and
safe_template instances is that if a placeholder is missing from
Another class is provided which derives from Template. This class
is called 'SafeTemplate' and supports rules identical to those
above. The difference between Template instances and SafeTemplate
instances is that in SafeTemplate if a placeholder is missing from
the interpolation mapping, no KeyError is raised. Instead, the
original placeholder is included in the result string unchanged.
For example:
>>> from string import template, safe_template
>>> from string import Template, SafeTemplate
>>> mapping = dict(name='Guido', country='the Netherlands')
>>> s = template('$who was born in $country')
>>> s = Template('$who was born in $country')
>>> print s % mapping
Traceback (most recent call last):
[...traceback omitted...]
KeyError: u'who'
>>> s = safe_template('$who was born in $country')
>>> s = SafeTemplate('$who was born in $country')
>>> print s % mapping
$who was born in the Netherlands
@ -135,12 +135,12 @@ Comparison to PEP 215
quite complex, and make it more difficult to see the substitution
placeholder in the original $-string.
The interesting thing is that the template class defined in this
The interesting thing is that the Template class defined in this
PEP has nothing to say about the values that are substituted for
the placeholders. Thus, with a little extra work, it's possible
to support PEP 215's functionality using existing Python syntax.
For example, one could define subclasses of template and dict that
For example, one could define subclasses of Template and dict that
allowed for a more complex placeholder syntax and a mapping that
evaluated those placeholders.
@ -150,17 +150,69 @@ Internationalization
The implementation supports internationalization magic by keeping
the original string value intact. In fact, all the work of the
special substitution rules are implemented by overriding the
__mod__() operator. However the string value of a template (or
safe_template) is the string that was passed to its constructor.
__mod__() operator. However the string value of a Template (or
SafeTemplate) is the string that was passed to its constructor.
This approach allows a gettext-based internationalized program to
use the template instance as a lookup into the catalog; in fact
gettext doesn't care that the catalog key is a template. Because
the value of the template is the original $-string, translators
use the Template instance as a lookup into the catalog; in fact
gettext doesn't care that the catalog key is a Template. Because
the value of the Template is the original $-string, translators
also never need to use %-strings. The right thing will happen at
run-time.
Open Issues
- Should the Template and SafeTemplate classes convert mapping
values to strings (or unicodes)? I.e. what should this code do:
>>> from string import Template
>>> Template('The cost was $amount euros') % {'amount': 7}
Should this raise an exception such as TypeError, or should this
return the string 'The cose was 7 euros'?
PEP author preference: no automatic stringification.
- The pattern for placeholders in the Template and SafeTemplate
classes matches Python identifiers. Some people want to match
Python attribute paths, e.g. "$os.path.sep". This can be useful
in some applications, however note that it is up to the
interpolation mapping to provide namespace lookup for the
attribute paths.
Should we include AttributeTemplate and SafeAttributeTemplate in
the standard library? What about more complex patterns such as
Python expressions?
PEP author preference: No, we don't include them for now. Such
classes are easily derived, and besides, we're not proposing to
include any interpolation mappings, and without such a
specialized mapping, a pattern matching attribute paths or
expressions aren't useful.
- Where does the Template and SafeTemplate classes live? Some
people have suggested creating a stringtools or stringlib module
to house these two classes. The PEP author has proposed a
re-organization of the existing string module, turning it into a
string package.
PEP author preference: There seems little consensus around
either suggestion, and since the classes are just a few lines of
Python, I propose no string module re-organization, but to add
these two classes to string.py.
- Should the $-placeholder rules be more strict? Specifically,
objections have been raised about 'magically' escaping $'s at
the end of strings, or in strings like '$100'. The suggestion
was that we add another matching group which matches bare $'s,
raising a ValueError if we find such a match.
PEP author preference: This sounds fine to me, although because
the pattern is part of the public interface for the class, we
will have to document that 4 groups are expected instead of 3.
References
[1] String Formatting Operations