The classes have been renamed Template and SafeTemplate. Also, a bunch of
open issues have been added.
This commit is contained in:
parent
b5815e3e63
commit
2042beaefb
94
pep-0292.txt
94
pep-0292.txt
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue