[Python-3000] Open Issues for string.format PEP

Talin talin at acm.org
Mon Apr 24 08:40:15 CEST 2006


Ian Bicking <ianb <at> colorstudy.com> writes:

> 
> Talin wrote:
> > Here's a condensed list of the open issues that have been raised by people
> > so far:
> > 
> > (Well, edited somewhat - I'm including 'major' issues, not minor nits -- we
> > can discuss those once the major issues are settled.)
> > 
> > 1) Whether to drop the optional parts of the proposal:
> >    -- support for field expressions (was: locals() support)
> >    -- support for direct access to current scope (was: locals() support)
> 
> It seems reasonable to implement this as a format() function right now, 
> and maybe test it out on a couple modules.  Doing so with or without 
> special locals() support isn't too hard, and then it will be possible to 
> see what change it makes in actual code.
> 
> The benefit of locals() (and maybe expression) support is going to be 
> when surrounding code can be easily removed -- the actual string 
> substitution isn't going to look much better.  The actual benefit is 
> hard to judge without representative chunks of code.

Yeah, the more I think about it, the more the issue of supporting locals and
field expressions seems like a whole different feature, deserving of its own PEP
and its own mailing list flamewars :)

I'm going to omit those sections from the next revision of the PEP.

> > 3) Role and usage of custom formatters:
> > 
> >    "string".fformat( formatter, ... )
> > 
> > vs.
> > 
> >    MyFormat( "string" ).format( ... )
> 
> MyFormat("string").format(...) doesn't seem right as a convention.  I 
> would assume my_formatter("string", ...), where my_formatter was built 
> through subclassing (but doesn't really need to look like a class or 
> instance).  I guess I don't see the need for string.Template-style 
> invocation, even if it uses string.Template-style subclassing.

The sample code I posted in another thread is intended to be a base for people
to experiment with various calling conventions.

For me, the most important aspects of custom formatters are:

1) I don't want to lose the feature of being able to specify alternate per-field
formatting.

2) The built-in 'format' method of strings and the custom formatters should
share as much code as possible. I'm thinking that both should just call a common
formatting engine that is used for both.

Other than that, I don't care what the calling syntax looks like.

3) I'd still like to be able to use custom formatters for things like
indentation, variable-width padding, and such.

Assuming that those constraints can be met, I'm still interested in what kinds
of calling conventions people would prefer.

(BTW, the name 'fformat' was chosen using the following rule: 'If you can't
think of a good name, at least think of something that's easy to type'. You can
always backfill an explanation later...)

> > 4) Should there be a way to pass in a dict argument without flattening it via
> > **args?
> 
> I think it might not be ambiguous in practice if the first argument 
> could be a dictionary.  Because you get:
> 
>    "{foo}".format(a_dict)
> 
> Since 'foo' isn't an integer and *no* keyword arguments were passed, you 
> assume a_dict is a dictionary.  Already "{0}" is going to look for 
> positional arguments even if there is a dictionary with a '0' key, and I 
> think that's just a reasonable limitation.  Then there's the case:
> 
>    "{0} is {result}".format(a_dict)
> 
> Is this an error?  I'm not sure; it doesn't really need to be, it'd just 
> evaluate to "{'result': 5} is 5" or something.  Potentially this would 
> be a problem, though:
> 
>    "{0} is {result}".format(value, **vars)
> 
> When vars was {}... statically it would be clear that you intended 
> {result} to come from vars, but at runtime you couldn't detect that. 
> But I can't really imagine where that would happen, especially if 
> there's no support for KeyError.

Waaaayy too much voodoo. I think that this kind of implicit deduction of "what
the programmer meant" is what people are trying to avoid. (And, if you'll
forgive me for saying so, it's rather Perl-ish.)

I want to go back for a moment to the original question. Whenever someone asks
me "how should we solve this problem?" the first thing I always ask is "do we
really need to?" Once we've answered that, we can then go on to the issue of
coming up with a solution.

> > 5) Should the implementation attempt to detect unused arguments?
> 
> Of course, just unused positional arguments would be detected.  Putting 
> the dict as the first argument might cause a problem here.

True. In general, if you pass a un-flattened dict, you probably want to disable
the unused argument checking altogether, because the whole reason for passing a
dict in the first place is so that you can cherry-pick specific values out of it.

-- Talin




More information about the Python-3000 mailing list