[Python-Dev] PEP 215 redux: toward a simplified consensus?

Jeff Epler jepler@unpythonic.dhs.org
Mon, 25 Feb 2002 15:01:06 -0600

On Mon, Feb 25, 2002 at 12:31:55PM -0800, Paul Prescod wrote:
> Yuck!
> String interopolation should be a *compile time* action, not an
> operator. One of the goals, in my mind, is to allow people to string
> interpolate without knowing what the locals() function does. After all,
> that function is otherwise useless for most Python programmers (and
> should probably be moved to an introspection module). 
> Your strategy requires the naive user to learn a) the $ syntax, b) the
> magic operator syntax and c) the meaning of the locals() function. Plus
> you've thrown away the idea that interpolation works as it does in the
> shell or in Perl/Awk/Ruby etc.
> At that point, in my mind, we're back where we started and should just
> use %. Well have reinvented it with a few small tweaks.
> Plus, operator-based evaluation has some security implications that
> compile time evaluation does not. In particular, if the left-hand thing
> can be any string then you have the potential of accidentally allowing
> the user to supply a string that allows him/her to introspect your local
> variables. That can't happen if the interpolation is done at compile
> time.

But how do you internationalize your program once you use $-subs?  The
great strength of %-formats, and the *printf functions that inspired
them, are that the interpretation of the format takes place at runtime.
(printf has added positional specifiers, spelled like "%1$s", to permit
reordering of items in the format, while Python has added
key-specifiers, spelled like "%(id)s", but they're about equally

With %-subs, we can write
    def gettext(s):
	""" Return the localized version of s from the message catalog """
	return s

    def print_chance(who, chance):
	print gettext("%(who)s has a %(percent).2f%% chance of surviving") % {
		'who': who,
		'percent': chance * 100}

    print_chance("Jeff", 1./3)

I'm not interested in any proposal that turns code that's easy to
internationalize (just add calls to gettext(), commonly spelled _(),
around each string that needs translating, then fix up the places where
the programmer was too clever) into code that's impossible to
internationalize by design.