[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 }

    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

    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.


    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

    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

    [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