[Python-Dev] Alternative placeholder delimiters for PEP 292
Andrew Durdin
adurdin at gmail.com
Mon Aug 30 08:11:34 CEST 2004
A Yet Simpler Proposal, modifying that of PEP 292
I propose that the Template module not use $ to set off
placeholders; instead, placeholders are delimited by braces {}.
The following rules for {}-placeholders apply:
1. {{ and }} are escapes; they are replaced with a single { or }
respectively.
2. {identifier} names a substitution placeholder matching a
mapping key of "identifier". By default, "identifier" must
spell a Python identifier as defined in Identifiers and
Keywords[1].
No other characters have special meaning.
If the left-brace { is unmatched, appears at the end of the
string, or is followed by any non-identifier character, a
ValueError will be raised at interpolation time[2].
If a single, unmatched right-brace } occurs in the string, a
ValueError will be raised at interpolation time. This avoids
ambiguity: did the user want a single right-brace, or did they
inadvertently omit the left-brace? This will also cause a
probably erroneous "{foo}}" or "{{foo}" to raise a ValueError.
Rationale
There are several reasons for preferring the paired delimiters {}
to a single prefixed $:
1. The placeholder name stands out more clearly from its
surroundings, due to the presence of a closing delimiter, and
also to the fact that the braces bear less resemblance to any
alphabetic characters than the dollar sign:
"Hello, {name}, how are you?" vs "Hello, $name, how are you?"
2. Only two characters have special meanings in the string, as
opposed to three. Additionally, dollar signs are expected to
be more often used in templated strings (e.g. for currency
values) than braces:
"The {item} costs ${price}." vs "The $item costs $$$price."
3. The placeholder syntax is consistent, and does not change even
when valid identifier characters follow the placeholder but
are not part of the placeholder:
"Look at the {plural}s!" vs "Look at the ${plural}s!"
4. The template substitution could be changed in future to
support dotted names without breaking existing code. The
example below would break if the $-template were changed to
allow dotted names:
"Evaluate {obj}.__doc__" vs "Evaluate $obj.__doc__"
There are two drawbacks to the proposal when compared with
$-templates:
1. An extra character must be typed for each placeholder in the
common case:
"{name}, welcome to {site}!" vs "$name, welcome to $site!"
2. Templated strings containing braces become more complicated:
"dict = {{'{key}': '{value}'}}" vs "dict = {'$key': '$value'}"
The first is not a real issue; the extra closing braces needed
for the placeholder when compared with the number of other
characters in the templated string will usually be insignificant.
Furthermore, the {}-placeholders require fewer characters to be
typed in the less common case when valid identifier characters
follow the placeholder but are not part of it.
The need for braces in a templated string is not expected to
occur frequently. Because of this, the second drawback is
considered of minor importance.
Reference Implementation
If the general nature of feedback on this proposal is positive,
or expressive of interest in an implementation, then a reference
implementation will be created forthwith.
References and Notes
[1] Identifiers and Keywords
http://www.python.org/doc/current/ref/identifiers.html
[2] The requirement for interpolation-time error raising is the
same as in PEP 292. Although not a part of this proposal, I
suggest that it would be better if the error occured when the
Template instance is created.
It is worth noting that the PEP 292 reference implementation
(in python/nondist/sandbox/string/string/template.py) does
not fully conform to the PEP as regards raising errors for
invalid template strings:
>>> t = Template("This should cause an error: $*")
>>> t % {}
u'This should cause an error: $*'
>>> t = Template("This also should cause an error: $")
>>> t % {}
u'This also should cause an error: $'
More information about the Python-Dev
mailing list