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
|
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
|
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
|
substitution; its value contains placeholders, introduced with the
|
||||||
$ character. The following rules for $-placeholders apply:
|
$ 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
|
If the $ character appears at the end of the line, or is followed
|
||||||
by any other character than those described above, it is treated
|
by any other character than those described above, it is treated
|
||||||
as if it had been escaped, appearing in the resulting string
|
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
|
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
|
the placeholder. For example, a derived class could allow for
|
||||||
periods in the placeholder (e.g. to support a kind of dynamic
|
periods in the placeholder (e.g. to support a kind of dynamic
|
||||||
namespace and attribute path lookup).
|
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:
|
using traditional Python syntax. For example:
|
||||||
|
|
||||||
>>> from string import template
|
>>> from string import Template
|
||||||
>>> mapping = dict(name='Guido', country='the Netherlands')
|
>>> mapping = dict(name='Guido', country='the Netherlands')
|
||||||
>>> s = template('${name} was born in ${country}')
|
>>> s = Template('${name} was born in ${country}')
|
||||||
>>> print s % mapping
|
>>> print s % mapping
|
||||||
Guido was born in the Netherlands
|
Guido was born in the Netherlands
|
||||||
|
|
||||||
Another class is provided which derives from template. This class
|
Another class is provided which derives from Template. This class
|
||||||
is called 'safe_template' and supports rules identical to those
|
is called 'SafeTemplate' and supports rules identical to those
|
||||||
above. The difference between template instances and
|
above. The difference between Template instances and SafeTemplate
|
||||||
safe_template instances is that if a placeholder is missing from
|
instances is that in SafeTemplate if a placeholder is missing from
|
||||||
the interpolation mapping, no KeyError is raised. Instead, the
|
the interpolation mapping, no KeyError is raised. Instead, the
|
||||||
original placeholder is included in the result string unchanged.
|
original placeholder is included in the result string unchanged.
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
>>> from string import template, safe_template
|
>>> from string import Template, SafeTemplate
|
||||||
>>> mapping = dict(name='Guido', country='the Netherlands')
|
>>> mapping = dict(name='Guido', country='the Netherlands')
|
||||||
>>> s = template('$who was born in $country')
|
>>> s = Template('$who was born in $country')
|
||||||
>>> print s % mapping
|
>>> print s % mapping
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
[...traceback omitted...]
|
[...traceback omitted...]
|
||||||
KeyError: u'who'
|
KeyError: u'who'
|
||||||
>>> s = safe_template('$who was born in $country')
|
>>> s = SafeTemplate('$who was born in $country')
|
||||||
>>> print s % mapping
|
>>> print s % mapping
|
||||||
$who was born in the Netherlands
|
$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
|
quite complex, and make it more difficult to see the substitution
|
||||||
placeholder in the original $-string.
|
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
|
PEP has nothing to say about the values that are substituted for
|
||||||
the placeholders. Thus, with a little extra work, it's possible
|
the placeholders. Thus, with a little extra work, it's possible
|
||||||
to support PEP 215's functionality using existing Python syntax.
|
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
|
allowed for a more complex placeholder syntax and a mapping that
|
||||||
evaluated those placeholders.
|
evaluated those placeholders.
|
||||||
|
|
||||||
|
@ -150,17 +150,69 @@ Internationalization
|
||||||
The implementation supports internationalization magic by keeping
|
The implementation supports internationalization magic by keeping
|
||||||
the original string value intact. In fact, all the work of the
|
the original string value intact. In fact, all the work of the
|
||||||
special substitution rules are implemented by overriding the
|
special substitution rules are implemented by overriding the
|
||||||
__mod__() operator. However the string value of a template (or
|
__mod__() operator. However the string value of a Template (or
|
||||||
safe_template) is the string that was passed to its constructor.
|
SafeTemplate) is the string that was passed to its constructor.
|
||||||
|
|
||||||
This approach allows a gettext-based internationalized program to
|
This approach allows a gettext-based internationalized program to
|
||||||
use the template instance as a lookup into the catalog; in fact
|
use the Template instance as a lookup into the catalog; in fact
|
||||||
gettext doesn't care that the catalog key is a template. Because
|
gettext doesn't care that the catalog key is a Template. Because
|
||||||
the value of the template is the original $-string, translators
|
the value of the Template is the original $-string, translators
|
||||||
also never need to use %-strings. The right thing will happen at
|
also never need to use %-strings. The right thing will happen at
|
||||||
run-time.
|
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
|
References
|
||||||
|
|
||||||
[1] String Formatting Operations
|
[1] String Formatting Operations
|
||||||
|
|
Loading…
Reference in New Issue